Компьютерные игры стали популярным видом игровой деятельности и наиболее выгодным коммерческим продуктом на современном рынке.
Индустрия компьютерных игр — часть современной мировой экономики. Это совокупность различных компаний, сообществ и отдельных личностей, а также технологий и процессов, которые вместе образуют полный цикл производства (разработка, продажа, продвижение, потребление) компьютерных игр. Конкурентное преимущество рынка компьютерных игр заключается в том, что он менее других секторов экономики подвержен внезапным колебаниям.
С развитием интернета вырос интерес и к международной электронной торговле. Сейчас продукт (с помощью множества сервисов) можно приобрести из любой точки мира, имеющей доступ к интернету.
Интернет-магазин компьютерных игр — это электронная площадка (онлайн-ресурс), на котором можно приобрести цифровые копии компьютерных игр. Такие магазины обеспечивают быстрый и удобный доступ к играм. Они могут предлагать к продаже ключи для активации игр или ссылки для скачивания игр. Обычно в таких магазинах можно найти широкий ассортимент игр для различных платформ (персонального компьютера, игровых консолей, мобильных устройств). Оплата за игры может осуществляться различными электронными способами, включая использование банковских карт и электронных кошельков. А если обеспечить англоязычную поддержку и сервис, то можно продавать компьютерные игры по всему миру.
Чтобы интернет-магазин приносил прибыль, необходимо разработать эффективную стратегию его продвижения и спланировать маркетинговые мероприятия. Прежде всего нужно сделать ставку на потенциально популярный и успешный продукт.
Потенциально популярный продукт — это товар, который может стать популярным в будущем. Для выявления такого продукта и прогнозирования продаж необходимо проанализировать объём рынка и спрос, понять, какие компьютерные игры востребованы на рынке и кто является лидером продаж — найти бестселлеры. Важно отличаться от конкурентов, поэтому необходимо сделать правильный выбор целевой аудитории и предложить ей что-то новое и интересное.
Успешность компьютерной игры может оцениваться по различным критериям, включая количество проданных копий, популярность в онлайн-сообществах, критические отзывы и рейтинги.
Для прогнозирования продаж компьютерных игр и подбора факторов влияния на продажи нужно:
Для проведения анализа необходимы данные. Такие данные можно получить из открытых источников.
Открытые источники, собирающие данные о продажах компьютерных игр, — это ресурсы, на которых публикуются данные о количестве проданных экземпляров игр, их доходности, рейтингах популярности и других характеристиках. Такие источники позволяют отслеживать динамику продаж и успех игр от разных издателей и разработчиков, а также проводить анализ рынка компьютерных игр.
В нашем распоряжении находятся данные о продажах игр до 2016 года в различных регионах мира, полученные из открытых источников. По каждой проданной игре доступны данные о выпуске игры, о жанрах и платформах, информация об объёме продаж в регионах, а также экспертные и пользовательские оценки и рейтинг, присвоенный ESRB.
Цель исследования: выявить признаки, определяющие успешность компьютерной игры.
Задачи исследования:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import sys
import os
import warnings
from scipy import stats as st
pd.set_option('display.max_columns', None)
np.set_printoptions(threshold=sys.maxsize)
warnings.filterwarnings('ignore')
Все данные хранятся в одном файле.
Файл данных games.csv имеет формат CSV.
pth1 = r'C:\Users\Георгий\Documents\DS_projects\games.csv'
pth2 = '/datasets/games.csv'
pth3 = '/content/games.csv'
if os.path.exists(pth1):
data = pd.read_csv(pth1)
elif os.path.exists(pth2):
data = pd.read_csv(pth2)
elif os.path.exists(pth3):
data = pd.read_csv(pth3)
else:
print('Something is wrong')
Убедимся, что данные подгрузились верно, без ошибок.
Для этого выведем первые 10 строк и последние 10 строк набора данных.
data.head(10)
| Name | Platform | Year_of_Release | Genre | NA_sales | EU_sales | JP_sales | Other_sales | Critic_Score | User_Score | Rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Wii Sports | Wii | 2006.0 | Sports | 41.36 | 28.96 | 3.77 | 8.45 | 76.0 | 8 | E |
| 1 | Super Mario Bros. | NES | 1985.0 | Platform | 29.08 | 3.58 | 6.81 | 0.77 | NaN | NaN | NaN |
| 2 | Mario Kart Wii | Wii | 2008.0 | Racing | 15.68 | 12.76 | 3.79 | 3.29 | 82.0 | 8.3 | E |
| 3 | Wii Sports Resort | Wii | 2009.0 | Sports | 15.61 | 10.93 | 3.28 | 2.95 | 80.0 | 8 | E |
| 4 | Pokemon Red/Pokemon Blue | GB | 1996.0 | Role-Playing | 11.27 | 8.89 | 10.22 | 1.00 | NaN | NaN | NaN |
| 5 | Tetris | GB | 1989.0 | Puzzle | 23.20 | 2.26 | 4.22 | 0.58 | NaN | NaN | NaN |
| 6 | New Super Mario Bros. | DS | 2006.0 | Platform | 11.28 | 9.14 | 6.50 | 2.88 | 89.0 | 8.5 | E |
| 7 | Wii Play | Wii | 2006.0 | Misc | 13.96 | 9.18 | 2.93 | 2.84 | 58.0 | 6.6 | E |
| 8 | New Super Mario Bros. Wii | Wii | 2009.0 | Platform | 14.44 | 6.94 | 4.70 | 2.24 | 87.0 | 8.4 | E |
| 9 | Duck Hunt | NES | 1984.0 | Shooter | 26.93 | 0.63 | 0.28 | 0.47 | NaN | NaN | NaN |
data.tail(10)
| Name | Platform | Year_of_Release | Genre | NA_sales | EU_sales | JP_sales | Other_sales | Critic_Score | User_Score | Rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 16705 | 15 Days | PC | 2009.0 | Adventure | 0.00 | 0.01 | 0.00 | 0.0 | 63.0 | 5.8 | NaN |
| 16706 | Men in Black II: Alien Escape | GC | 2003.0 | Shooter | 0.01 | 0.00 | 0.00 | 0.0 | NaN | tbd | T |
| 16707 | Aiyoku no Eustia | PSV | 2014.0 | Misc | 0.00 | 0.00 | 0.01 | 0.0 | NaN | NaN | NaN |
| 16708 | Woody Woodpecker in Crazy Castle 5 | GBA | 2002.0 | Platform | 0.01 | 0.00 | 0.00 | 0.0 | NaN | NaN | NaN |
| 16709 | SCORE International Baja 1000: The Official Game | PS2 | 2008.0 | Racing | 0.00 | 0.00 | 0.00 | 0.0 | NaN | NaN | NaN |
| 16710 | Samurai Warriors: Sanada Maru | PS3 | 2016.0 | Action | 0.00 | 0.00 | 0.01 | 0.0 | NaN | NaN | NaN |
| 16711 | LMA Manager 2007 | X360 | 2006.0 | Sports | 0.00 | 0.01 | 0.00 | 0.0 | NaN | NaN | NaN |
| 16712 | Haitaka no Psychedelica | PSV | 2016.0 | Adventure | 0.00 | 0.00 | 0.01 | 0.0 | NaN | NaN | NaN |
| 16713 | Spirits & Spells | GBA | 2003.0 | Platform | 0.01 | 0.00 | 0.00 | 0.0 | NaN | NaN | NaN |
| 16714 | Winning Post 8 2016 | PSV | 2016.0 | Simulation | 0.00 | 0.00 | 0.01 | 0.0 | NaN | NaN | NaN |
Размер набора данных:
data.shape
(16715, 11)
Количество дубликатов в наименованиях признаков:
data.columns.duplicated().sum()
0
Уникальные наименования признаков:
data.columns.sort_values().tolist()
['Critic_Score', 'EU_sales', 'Genre', 'JP_sales', 'NA_sales', 'Name', 'Other_sales', 'Platform', 'Rating', 'User_Score', 'Year_of_Release']
Количество элементов данных:
data.size
183865
Типы данных набора данных:
data.dtypes.value_counts()
float64 6 object 5 dtype: int64
Пропущенные значения в данных:
data.isna().sum().sort_values()
Platform 0 NA_sales 0 EU_sales 0 JP_sales 0 Other_sales 0 Name 2 Genre 2 Year_of_Release 269 User_Score 6701 Rating 6766 Critic_Score 8578 dtype: int64
Распределение пропущенных значений в наборе данных:
sns.heatmap(data.isna(), cmap=sns.color_palette(['#000000', '#ffffff']))
plt.title('Тепловая карта распределения пропущенных значений')
plt.xlabel('Название признака')
plt.ylabel('Номер записи')
plt.show()
Количество признаков без пропущенных значений:
(data.isna().sum() == 0).sum()
5
Общее количество пропущенных значений:
data.isna().sum().sum()
22318
Промежуточный вывод
Приведение названий столбцов к нижнему регистру.
data.columns = data.columns.str.lower()
data.columns.tolist()
['name', 'platform', 'year_of_release', 'genre', 'na_sales', 'eu_sales', 'jp_sales', 'other_sales', 'critic_score', 'user_score', 'rating']
data.head()
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Wii Sports | Wii | 2006.0 | Sports | 41.36 | 28.96 | 3.77 | 8.45 | 76.0 | 8 | E |
| 1 | Super Mario Bros. | NES | 1985.0 | Platform | 29.08 | 3.58 | 6.81 | 0.77 | NaN | NaN | NaN |
| 2 | Mario Kart Wii | Wii | 2008.0 | Racing | 15.68 | 12.76 | 3.79 | 3.29 | 82.0 | 8.3 | E |
| 3 | Wii Sports Resort | Wii | 2009.0 | Sports | 15.61 | 10.93 | 3.28 | 2.95 | 80.0 | 8 | E |
| 4 | Pokemon Red/Pokemon Blue | GB | 1996.0 | Role-Playing | 11.27 | 8.89 | 10.22 | 1.00 | NaN | NaN | NaN |
По своему содержанию все данные можно разделить на несколько категорий:
*Характеристики компьютерных игр*
С точки зрения действующего правового регулирования специфические черты компьютерной игры позволяют отнести её к разновидности компьютерной программы/программы для электронно-вычислительных машин (ЭВМ) либо к разновидности мультимедийной продукции.
Компьютерная игра — разновидность мультимедийного продукта, представляющего собой комплексное синтетическое произведение, созданное на особом уровне сотрудничества коллектива авторов.
Компьютерная игра — техническая игра, в которой игровое поле находится под управлением ЭВМ или воспроизводится на экране дисплея.
Компьютерная игра — компьютерная программа, служащая для организации игрового процесса (геймплея), связи с партнёрами по игре, или сама выступающая в качестве партнёра.
Для создания уникальной идентичности компьютерной игры и облегчения её поиска и распространения среди пользователей игре необходимо давать название.
Название игры — это уникальное имя (словесное обозначение) компьютерной игры, по которому её можно идентифицировать и выделить из множества всех компьютерных игр.
Варианты названий компьютерных игр ограничены только фантазией разработчиков. Название может отражать основной сюжет и цель игры. Оно может содержать ключевые слова или фразы, которые помогают пользователям понять суть игры. Кроме того, некоторые игры могут иметь подзаголовки или дополнительные обозначения, указывающие на жанр, платформу, год выпуска.
name — название компьютерной игры
Признак является категориальным, номинальным.
Шкала измерения признака: номинальная шкала.
Год выпуска игры — это год, когда компьютерная игра была разработана и выпущена на рынок.
Это важная информация для игроков, так как она позволяет определить, насколько игра старая или новая, и как она соотносится с современными стандартами качества компьютерных игр. Также по году выпуска пользователь может определять совместимость игры с операционной системой и техническими характеристиками компьютера или игровой консоли.
year_of_release — год выпуска компьютерной игры
Признак является количественным, дискретным.
Шкала измерения признака: интервальная шкала.
Современные компьютерные игры, как правило, издаются несколько раз: для разных стран и регионов мира, а также для разных платформ.
Игровые платформы — аппаратно-программные системы, используемые для запуска, управления и игры в компьютерные игры.
Все игровые платформы имеют свои особенности, некоторые из которых включают в себя разные виды графики, звука и множество других функций. Каждая платформа имеет свои уникальные игры и совместимость с различными аксессуарами, которые могут варьироваться в зависимости от платформы.
Среди основных видов игровых платформ можно выделить:
Кроме того, существуют и другие виды игровых платформ:
Personal computer (PC) — персональный компьютер.
Игровая приставка (игровая консоль) — специализированное электронное устройство, предназначенное для видеоигр. Для таких устройств, в отличие от персональных компьютеров, запуск и воспроизведение видеоигр является основной задачей.
Портативная игровая система (портативная игровая приставка) — лёгкое, компактное, портативное электронное устройство, предназначенное для того, чтобы играть в видеоигры. От игровых приставок (игровых консолей) такие устройства отличаются компактностью и мобильностью; игровой контроллер, экран и звуковоспроизводящие элементы, как правило, являются здесь частью самого устройства.
Портативные консоли и другие игровые системы часто группируются по годам выпуска, связанным с поколениями домашних консолей.
Поколения игровых систем — это группы игровых систем, выпущенных в определённый период времени и имеющих общие характеристики по техническим спецификациям или функциональности. Игровые системы делятся на поколения, чтобы облегчить сравнение их возможностей и продолжительности жизненного цикла.
Поколения различаются по многим параметрам, например, по процессору, графике, звуковой поддержке, способности к сетевым функциям и т. д. Игровые разработчики учитывают различия между поколениями при создании и оптимизации игр для консолей.
| Второе поколение игровых систем | (1976–1984) |
|---|---|
Atari 2600 (2600) — игровая приставка производства Atari (США). Выпущена в 1977 г. Поддержка прекращена в 1992 г.
| Третье поколение игровых систем | (1983–1992) |
|---|---|
Nintendo Entertainment System (NES) — игровая приставка производства Nintendo (Япония). Выпущена в 1983 г. Поддержка прекращена в 2003 г.
| Четвёртое поколение игровых систем | (1987–1996) |
|---|---|
Nintendo Game Boy (GB) — портативная игровая система производства Nintendo (Япония). Выпущена в 1989 г. Поддержка прекращена в 2003 г.
Sega Mega Drive/Genesis (GEN) — игровая приставка производства Sega (Япония). Выпущена в 1988 г. Поддержка прекращена в 1999 г.
Sega Game Gear (GG) — портативная игровая приставка производства Sega (Япония). Выпущена в 1990 г. Поддержка прекращена в 1997 г.
Super Nintendo Entertainment System (SNES) — игровая приставка производства Nintendo (Япония). Выпущена в 1990 г. Поддержка прекращена в 2005 г.
Neo Geo (NG) — игровая приставка производства SNK (Япония). Выпущена в 1990 г. Поддержка прекращена в 2007 г.
Sega Mega-CD (SCD) — дополнение к игровой приставке Sega Mega Drive производства Sega (Япония). Выпущена в 1991 г. Поддержка прекращена в 1996 г.
TurboGrafx-16 (TG16) — игровая приставка производства NEC (Япония). Выпущена в 1987 г. Поддержка прекращена в 1994 г.
| Пятое поколение игровых систем | (1993–2005) |
|---|---|
3DO Interactive Multiplayer (3DO) — игровая приставка производства Panasonic, Sanyo, Creative и Goldstar (Япония—Южная Корея—Сингапур). Выпущена в 1993 г. Поддержка прекращена в 1996 г.
Nintendo 64 (N64) — игровая приставка производства Nintendo (Япония) совместно с Silicon Graphics (США). Выпущена в 1996 г. Поддержка прекращена в 2002 г.
PC-FX (PCFX) — игровая приставка производства NEC (Япония). Выпущена в 1994 г. Поддержка прекращена в 1998 г.
PlayStation (PS) — игровая приставка производства Sony (Япония). Выпущена в 1994 г. Поддержка прекращена в 2006 г.
Sega Saturn (SAT) — игровая приставка производства Sega (Япония). Выпущена в 1994 г. Поддержка прекращена в 2000 г.
WonderSwan (WS) — портативная игровая консоль производства Bandai (Япония). Выпущена в 1999 г. Поддержка прекращена в 2003 г.
| Шестое поколение игровых систем | (1998–2013) |
|---|---|
Sega Dreamcast (DC) — игровая приставка производства Sega (Япония). Выпущена в 1998 г. Поддержка прекращена в 2001 г.
Game Boy Advance (GBA) — портативная игровая приставка производства Nintendo (Япония). Выпущена в 2001 г. Поддержка прекращена в 2008 г.
Nintendo GameCube (GC) — игровая приставка производства Nintendo (Япония). Выпущена в 2001 г. Поддержка прекращена в 2007 г.
PlayStation 2 (PS2) — игровая приставка производства Sony (Япония). Выпущена в 2000 г. Поддержка прекращена в 2013 г.
Xbox (XB) — игровая приставка производства Microsoft (США). Выпущена в 2001 г. Поддержка прекращена в 2009 г.
| Седьмое поколение игровых систем | (2004–2017) |
|---|---|
Nintendo DS (DS) — портативная игровая консоль производства Nintendo (Япония). Выпущена в 2004 г. Поддержка прекращена в 2013 г.
PlayStation 3 (PS3) — игровая приставка производства Sony (Япония). Выпущена в 2006 г. Поддержка прекращена в 2017 г. в Японии, в 2016 г. в Северной Америке.
PlayStation Portable (PSP) — портативная игровая приставка производства Sony (Япония). Выпущена в 2004 г. Поддержка прекращена в 2014 г.
Wii (Wii) — игровая приставка производства Nintendo (Япония). Выпущена в 2006 г. Поддержка прекращена в 2013 г.
Xbox 360 (X360) — игровая приставка производства Microsoft (США). Выпущена в 2005 г. Поддержка прекращена в 2016 г.
| Восьмое поколение игровых систем | (2012–н.в.) |
|---|---|
Nintendo 3DS (3DS) — портативная игровая приставка производства Nintendo (Япония). Выпущена в 2011 г. Поддержка прекращена в 2020 г.
PlayStation 4 (PS4) — игровая приставка производства Sony (Япония). Выпущена в 2013 г. Поддержка некоторых моделей прекращена в 2021 г.
PlayStation Vita (PSV) — портативная приставка производства Sony (Япония). Выпущена в 2011 г. Поддержка прекращена в 2019 г.
Wii U (WiiU) — игровая приставка производства Nintendo (Япония). Выпущена в 2012 г. Поддержка прекращена в 2017 г.
Xbox One (XOne) — игровая приставка производства Microsoft (США). Выпущена в 2013 г. Поддержка прекращена в 2020 г.
platform — название игровой платформы
Признак является категориальным, номинальным.
Шкала измерения признака: номинальная шкала.
Сегодня компьютерные игры фактически возводятся до уровня произведения искусства.
Жанр — род произведений в пределах какого-нибудь искусства, отличающийся особыми, только ему свойственными сюжетными, стилистическими признаками.
Одним из способов классификации компьютерных игр является деление их на жанры. Жанровая классификация появилась тогда, когда количество игр стало настолько большим, что игрокам требовалось быстрое и удобное средство для их описания и систематизации.
Вследствие того, что критерии принадлежности игры к тому или иному жанру не определены однозначно, в разных источниках данные о жанре конкретного проекта могут различаться. Тем не менее, существует консенсус, к которому пришли разработчики игр, что принадлежность игры к одному из основных жанров почти всегда можно определить однозначно.
Существуют игры с элементами нескольких жанров. Такие проекты причисляют либо к одному из жанров, который в игре является основным, либо сразу ко всем, присутствующим в игре, если они в равной мере составляют геймплей проекта.
Жанры игр могут подразделяться на поджанры.
Компьютерная ролевая игра (role-playing) — жанр компьютерных игр, подразумевающий контроль игрока над одним или несколькими персонажами, от лица которых игрок может совершать нарративные выборы.
Экшен ролевые игры (action) — поджанр компьютерных ролевых игр. К числу экшен относят такие ролевые игры, которые требовательны к физическим способностям игрока: зрительно-моторной координации, скорости реакции и т. д.
Шутер (shooter) — жанр компьютерных игр, основу игрового процесса которых составляет взаимодействие с внутриигровыми объектами посредством стрельбы в них.
Симулятор (simulation) — в этом компьютерном игровом жанре, геймер управляет объектами (машины, самолёты, лодки) или процессами (деятельностью или жизнью персонажа, города, мира).
Файтинг (fighting) — жанр компьютерных игр, имитирующих рукопашный бой малого числа персонажей в пределах ограниченного пространства, называемого ареной.
Платформер (platform) — игра, где персонаж, управляемый игроком, путешествует по игровому миру, переходя с платформы на платформу (прыгая над пропастями, переплывая реки, карабкаясь на стены) и попутно сражаясь со злодеями.
Стратегия (strategy) — игровой жанр компьютерных игр, нацеленный на управление процессами разных масштабов с целью решения поставленных внутри сюжета задач для достижения определённых целей.
Квест (adventure) — игра-повествование, в которой управляемый игроком герой продвигается по сюжету и взаимодействует с игровым миром посредством применения предметов, общения с другими персонажами и решения логических задач.
Квест-головоломка (puzzle) — подтип квеста, главной задачей которого является решение загадок, задач посредством исследования виртуального мира и взаимодействия с другими персонажами.
Спортивная игра (sports) — в этом игровом жанре компьютерных игр бывают различные симуляторы, делящиеся на два основных подкласса: а) симуляторы спорта — футбол, хоккей, баскетбол и т. д.; б) спортивный менеджер — организация и руководство спортивной командой.
Гоночная игра (racing) — жанр компьютерных игр с видом от первого или от третьего лица, в которых игрок принимает участие в гоночном соревновании среди наземных, водных, воздушных или космических транспортных средств.
Другие жанры (miscellaneous) — все жанры, которые не были упомянуты выше.
genre — жанр компьютерной игры
Признак является категориальным, номинальным.
Шкала измерения признака: номинальная шкала.
*Характеристики продаж*
Сведения о продажах компьютерной игры нужны для оценки её популярности и коммерческого успеха.
Объём продаж компьютерных игр — это количество игр, проданных за определённый период времени, как правило, за год.
Объём продаж может выражаться в денежном эквиваленте или в количестве проданных копий игр. Обычно этот показатель используется как показатель успеха игровой компании или отдельной игры.
Объём продаж компьютерных игр по регионам — это количество игр, проданных в разных частях мира.
Обычно объём продаж компьютерных игр исследуется в нескольких регионах, таких как Северная Америка, Европа, Япония и остальные регионы. Эта информация нужна, чтобы лучше понимать, где игры популярны, а где нужно увеличить маркетинговые усилия.
na_sales — объём продаж в Северной Америке (млн копий)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.
eu_sales — объём продаж в Европе (млн копий)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.
jp_sales — объём продаж в Японии (млн копий)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.
other_sales — объём продаж в остальных регионах (млн копий)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.
*Характеристики оценок*
Оценки пользователей и экспертов являются мерами качества продукта, его ценности и соответствия ожиданиям потребителя. Они нужны для выбора лучшего продукта и принятия обоснованных решений.
Оценки пользователей — это оценки, которые дают пользователи продукту на основании их собственного опыта использования.
Оценки экспертов — это мнение профессионалов или экспертов, которые проанализировали продукт на основе своих знаний и опыта в области использования продукта.
Экспертные оценки имеют большой вес и помогают установить стандарты качества, а оценки пользователей позволяют получить обратную связь и улучшить продукт в соответствии с их потребностями. Кроме того, оценки пользователей и экспертов могут служить рекламным инструментом, повышая доверие к продукту среди других потребителей.
critic_score — оценка критиков
Признак является количественным, непрерывным.
Шкала измерения признака: абсолютная шкала.
user_score — оценка пользователей
Признак является количественным, непрерывным.
Шкала измерения признака: абсолютная шкала.
Entertainment Software Rating Board (ESRB) — негосударственная саморегулируемая организация в индустрии компьютерных игр. Основана в 1994 году. Основная задача — помочь потребителям, особенно родителям, сделать осознанный выбор игр, в которые играют в их семьях.
Система рейтинга включает в себя
Рейтинг ESRB — это система классификации компьютерных игр в Северной Америке, которая помогает потребителям определить, подходит ли данная игра для их возрастной категории.
Рейтинговые категории определяются на основе содержания и предполагают соответствие возрасту.
Everyone (E) — "Для всех" — контент, как правило, подходит для всех возрастов. Может содержать минимальное количество мультипликационного, фэнтезийного или умеренного насилия и/или нечастое использование нецензурной лексики. Категория существует с 1998 года. До этого (с 1994 по 1998 года) обозначалась как Kids to Adults (K-A).
Early Childhood (EC) — "Для детей младшего возраста" — контент подходит для детей от 3 лет и не содержит материалов, которые родители могли бы счесть неподходящими. Существовал в период с 1994 по 2018 года.
Everyone 10+ (E10+) — "Для детей от 10 лет" — контент обычно подходит для детей в возрасте от 10 лет и старше. Может содержать больше мультипликационного, фэнтезийного или умеренного насилия, мягких выражений и/или минимальных, наводящих на размышления тем. Категория существует с 2005 года.
Teen (T) — "Для подростков от 13 лет" — контент, как правило, подходит для детей от 13 лет. Может содержать насилие, непристойные темы, грубый юмор, минимальное количество крови, имитацию азартных игр и/или нечастое использование ненормативной лексики. Категория существует с 1994 года.
Mature 17+ (M) — "Для подростков от 17 лет" — контент обычно подходит для лиц старше 17 лет. Может содержать жестокое насилие, кровь и увечья, материалы сексуального характера и/или ненормативную лексику. Категория существует с 1994 года.
Adults Only 18+ (AO) — "Для взрослых" — контент подходит только для взрослых в возрасте от 17 лет и старше. Может содержать продолжительные сцены жестокого насилия, изображения сексуального характера и/или азартные игры с реальной валютой. Категория существует с 1994 года.
Rating Pending (RP) — "Рейтинг ожидается" — окончательный рейтинг ESRB ещё не присвоен. Появляется только в маркетинговых и рекламных материалах, связанных с физическим носителем компьютерной игры (например, в коробке). Ожидается, что в будущем игра будет иметь рейтинг ESRB после процедуры его присвоения. Категория существует с 1994 года.
rating — рейтинг от организации Entertainment Software Rating Board (ESRB)
Признак является категориальным, номинальным.
Шкала измерения признака: номинальная шкала.
def graph(data):
'''
Функция строит диаграмму распределения значений и диаграмму размаха
исследуемых данных.
Принимает набор исследуемых данных.
'''
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 6))
ax1.set_title('Диаграмма распределения и диаграмма размаха' +
f'\nзначений признака {data.columns[0]}')
ax1.hist(data, bins=85)
ax1.tick_params(labelbottom=False)
ax1.set_ylabel('Частота')
ax2.boxplot(data, vert=False)
ax2.tick_params(left=False, labelleft=False)
ax2.set_xlabel('Значения признака')
plt.show()
data[['na_sales', 'eu_sales', 'jp_sales', 'other_sales', 'critic_score',
'user_score', 'year_of_release']].describe(include='all').round(2)
| na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | year_of_release | |
|---|---|---|---|---|---|---|---|
| count | 16715.00 | 16715.00 | 16715.00 | 16715.00 | 8137.00 | 10014 | 16446.00 |
| unique | NaN | NaN | NaN | NaN | NaN | 96 | NaN |
| top | NaN | NaN | NaN | NaN | NaN | tbd | NaN |
| freq | NaN | NaN | NaN | NaN | NaN | 2424 | NaN |
| mean | 0.26 | 0.15 | 0.08 | 0.05 | 68.97 | NaN | 2006.48 |
| std | 0.81 | 0.50 | 0.31 | 0.19 | 13.94 | NaN | 5.88 |
| min | 0.00 | 0.00 | 0.00 | 0.00 | 13.00 | NaN | 1980.00 |
| 25% | 0.00 | 0.00 | 0.00 | 0.00 | 60.00 | NaN | 2003.00 |
| 50% | 0.08 | 0.02 | 0.00 | 0.01 | 71.00 | NaN | 2007.00 |
| 75% | 0.24 | 0.11 | 0.04 | 0.03 | 79.00 | NaN | 2010.00 |
| max | 41.36 | 28.96 | 10.22 | 10.57 | 98.00 | NaN | 2016.00 |
data['user_score'].sort_values().unique()
array(['0', '0.2', '0.3', '0.5', '0.6', '0.7', '0.9', '1', '1.1', '1.2',
'1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '2', '2.1', '2.2',
'2.3', '2.4', '2.5', '2.6', '2.7', '2.8', '2.9', '3', '3.1', '3.2',
'3.3', '3.4', '3.5', '3.6', '3.7', '3.8', '3.9', '4', '4.1', '4.2',
'4.3', '4.4', '4.5', '4.6', '4.7', '4.8', '4.9', '5', '5.1', '5.2',
'5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '6', '6.1', '6.2',
'6.3', '6.4', '6.5', '6.6', '6.7', '6.8', '6.9', '7', '7.1', '7.2',
'7.3', '7.4', '7.5', '7.6', '7.7', '7.8', '7.9', '8', '8.1', '8.2',
'8.3', '8.4', '8.5', '8.6', '8.7', '8.8', '8.9', '9', '9.1', '9.2',
'9.3', '9.4', '9.5', '9.6', '9.7', 'tbd', nan], dtype=object)
graph(pd.DataFrame(data.loc[data['user_score'].notna() &
(data['user_score'] != 'tbd'), 'user_score']).astype('float'))
for column in ['na_sales', 'eu_sales', 'jp_sales', 'other_sales',
'critic_score', 'year_of_release']:
graph(pd.DataFrame(data.loc[data[column].notna(), column]))
na_sales — объём продаж в Северной Америке (млн копий)
Значения определены для всех записей.
Значения определены с точностью до 0,01 млн копий.
Минимальное значение — 0, максимальное значение — 41,36 млн копий.
Среднее арифметическое значение равно 0,26 млн копий, медиана — 0,08 млн копий.
Не менее четверти всех записей содержит значение 0. Среднее арифметическое сильно отличается от медианы и близко к значению третьего квартиля (0,24 млн копий). Такое происходит потому, что в наборе данных есть значения, сильно отличающиеся от остальных значений. На диаграмме размаха они не накрываются "ящиком с усами", наблюдается длинный хвост справа на диаграмме распределения и диаграмме размаха.
eu_sales — объём продаж в Европе (млн копий)
Значения определены для всех записей.
Значения определены с точностью до 0,01 млн копий.
Минимальное значение — 0, максимальное значение — 28,96 млн копий.
Среднее арифметическое значение равно 0,15 млн копий, медиана — 0,02 млн копий.
Не менее четверти всех записей содержит значение 0. Среднее арифметическое сильно отличается от медианы и больше значения третьего квартиля (0,11 млн копий). Такое происходит потому, что в наборе данных есть значения, сильно отличающиеся от остальных значений. На диаграмме размаха они не накрываются "ящиком с усами", наблюдается длинный хвост справа на диаграмме распределения и диаграмме размаха.
jp_sales — объём продаж в Японии (млн копий)
Значения определены для всех записей.
Значения определены с точностью до 0,01 млн копий.
Минимальное значение — 0, максимальное значение — 10,22 млн копий.
Среднее арифметическое значение равно 0,08 млн копий, медиана — 0.
Не менее половины всех записей содержит значение 0. Среднее арифметическое сильно отличается от медианы и больше значения третьего квартиля (0,04 млн копий). Такое происходит потому, что в наборе данных есть значения, сильно отличающиеся от остальных значений. На диаграмме размаха они не накрываются "ящиком с усами", наблюдается длинный хвост справа на диаграмме распределения и диаграмме размаха.
other_sales — объём продаж в остальных регионах (млн копий)
Значения определены для всех записей.
Значения определены с точностью до 0,01 млн копий.
Минимальное значение — 0, максимальное значение — 28,96 млн копий.
Среднее арифметическое значение равно 0,05 млн копий, медиана — 0,01 млн копий.
Не менее четверти всех записей содержит значение 0. Среднее арифметическое сильно отличается от медианы и близко к значению третьего квартиля (0,03 млн копий). Такое происходит потому, что в наборе данных есть значения, сильно отличающиеся от остальных значений. На диаграмме размаха они не накрываются "ящиком с усами", наблюдается длинный хвост справа на диаграмме распределения и диаграмме размаха.
critic_score — оценка критиков
Значения определены для 8137 записи — это 49 % всех записей.
Значения определены с точностью до 1.
Значения признака могут быть расположены в интервале от 0 до 100, включительно.
Минимальное значение — 13, максимальное значение — 98.
Среднее арифметическое значение равно 69, медиана — 71.
Первый и третий квартили (60 и 79, соответственно) расположены близко к медианному значению. Среднее арифметическое и медиана практически равны. Распределение унимодальное, смещено вправо. Небольшой хвост наблюдается слева — эти значения также наблюдаются на диаграмме размаха.
user_score — оценка пользователей
Значения определены для 10014 записей — это 60 % всех записей.
Значения определены с точностью до 0,1.
Значения признака могут быть расположены в интервале от 0 до 10, включительно.
Минимальное значение — 0, максимальное значение — 9,7.
Среди значений встречается tbd — это мода, её частота 2424.
year_of_release — год выпуска компьютерной игры
Значения определены для 16446 записей — это 98 % всех записей.
Значения определены с точностью до 1 года.
Минимальное значение — 1980 год, максимальное значение — 2016 год.
Медиана — 2007 год.
Первый и третий квартили (2003 и 2010 года, соответственно) расположены близко к медиане. Распределение унимодальное, смещено вправо. Наблюдается "хвост" слева — эти значения не накрываются "ящиком с усами" на диаграмме размаха.
data[['name', 'platform', 'genre', 'rating']].describe()
| name | platform | genre | rating | |
|---|---|---|---|---|
| count | 16713 | 16715 | 16713 | 9949 |
| unique | 11559 | 31 | 12 | 8 |
| top | Need for Speed: Most Wanted | PS2 | Action | E |
| freq | 12 | 2161 | 3369 | 3990 |
data['name'].value_counts().head()
Need for Speed: Most Wanted 12 Ratatouille 9 LEGO Marvel Super Heroes 9 FIFA 14 9 Madden NFL 07 9 Name: name, dtype: int64
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 6))
ax1.set_title('Диаграмма распределения и диаграмма размаха' +
'\nколичества различных значений признака name')
ax1.hist(data['name'].value_counts(), bins=100)
ax1.tick_params(labelbottom=False)
ax1.set_ylabel('Частота')
ax2.boxplot(data['name'].value_counts(), vert=False)
ax2.tick_params(left=False, labelleft=False)
ax2.set_xlabel('Количество различных значения признака')
plt.show()
name — название компьютерной игры
Значения определены для 16 713 записей — это почти 100 % записей.
Мода — Need for Speed: Most Wanted, её частота — 12.
Всего в наборе данных встречается 11 559 уникальных значений наименований компьютерных игр.
Большинство значений встречается в наборе данных один раз, но есть и такие, которые встречаются два и более раз.
Некоторые названия игр содержат сведения о регионах продаж.
data['platform'].value_counts()
PS2 2161 DS 2151 PS3 1331 Wii 1320 X360 1262 PSP 1209 PS 1197 PC 974 XB 824 GBA 822 GC 556 3DS 520 PSV 430 PS4 392 N64 319 XOne 247 SNES 239 SAT 173 WiiU 147 2600 133 NES 98 GB 98 DC 52 GEN 29 NG 12 SCD 6 WS 6 3DO 3 TG16 2 GG 1 PCFX 1 Name: platform, dtype: int64
plt.figure(figsize=(15, 3))
plt.title('Диаграмма распределения количества значений признака platform')
data['platform'].value_counts().sort_index().plot(kind='bar', rot=0)
plt.xlabel('Платформа')
plt.ylabel('Частота')
plt.show()
platform — название игровой платформы
Значения определены для всех записей.
Мода — PS2, её частота — 2161.
Минимальная частота — 1. Медианная частота — около 250.
Всего в наборе данных встречается 31 наименование платформ.
Менее 10 раз в наборе данных встречаются 6 наименований игровых платформ (редкие значения). Более 1000 раз в наборе данных встречаются 7 наименований игровых платформ (распространённые значения).
data['genre'].value_counts()
Action 3369 Sports 2348 Misc 1750 Role-Playing 1498 Shooter 1323 Adventure 1303 Racing 1249 Platform 888 Simulation 873 Fighting 849 Strategy 683 Puzzle 580 Name: genre, dtype: int64
plt.figure(figsize=(15, 3))
plt.title('Диаграмма распределения количества значений признака genre')
data['genre'].value_counts().sort_index().plot(kind='bar', rot=0)
plt.xlabel('Жанр')
plt.ylabel('Частота')
plt.show()
genre — жанр компьютерной игры
Значения определены для 16713 записей — это почти 100 % записей.
Мода — Action, её частота — 3369.
Минимальная частота — 580, соответствует значению Puzzle. Медианная частота — около 1300.
Всего в наборе данных присутствует 12 наименований жанров компьютерных игр.
data['rating'].value_counts()
E 3990 T 2961 M 1563 E10+ 1420 EC 8 K-A 3 RP 3 AO 1 Name: rating, dtype: int64
plt.figure(figsize=(15, 3))
plt.title('Диаграмма распределения количества значений признака rating')
data['rating'].value_counts().sort_index().plot(kind='bar', rot=0)
plt.xlabel('Рейтинг')
plt.ylabel('Частота')
plt.show()
rating — рейтинг от организации ESRB
Значения признака определены для 9949 записей — это 60 % всех записей.
Мода — категория E, её частота — 3990.
Минимальная частота — 1, соответствует категории AO.
Всего в наборе данных 8 различных категорий рейтинга ESRB.
В наборе данных 4 значения встречаются менее 10 раз (редкие значения) и 4 значения встречаются более 1000 раз (распространённые значения).
Промежуточный вывод
Прежде чем провести обработку текстовых значений признака genre, необходимо обработать записи с пропущенными значениями в этом признаке.
data[data['genre'].isna()]
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 659 | NaN | GEN | 1993.0 | NaN | 1.78 | 0.53 | 0.00 | 0.08 | NaN | NaN | NaN |
| 14244 | NaN | GEN | 1993.0 | NaN | 0.00 | 0.00 | 0.03 | 0.00 | NaN | NaN | NaN |
В двух записях отсутствуют сведения о жанре. В них также отсутствуют сведения о названии компьютерной игры. Вероятно, во время сбора данных или копирования произошла техническая ошибка, приведшая к потере данных в этих признаках.
Восстановить сведения в этих записях не представляется возможным. Поэтому их необходимо удалить.
data.dropna(subset=['genre'], inplace=True)
data['genre'].isna().sum()
0
Приведём наименования жанров к нижнему регистру.
data['genre'] = data['genre'].str.lower()
data['genre'].sort_values().unique()
array(['action', 'adventure', 'fighting', 'misc', 'platform', 'puzzle',
'racing', 'role-playing', 'shooter', 'simulation', 'sports',
'strategy'], dtype=object)
Среди значений признака user_score есть одно нечисловое значение — 'tbd'.
data['user_score'].sort_values().unique()
array(['0', '0.2', '0.3', '0.5', '0.6', '0.7', '0.9', '1', '1.1', '1.2',
'1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '2', '2.1', '2.2',
'2.3', '2.4', '2.5', '2.6', '2.7', '2.8', '2.9', '3', '3.1', '3.2',
'3.3', '3.4', '3.5', '3.6', '3.7', '3.8', '3.9', '4', '4.1', '4.2',
'4.3', '4.4', '4.5', '4.6', '4.7', '4.8', '4.9', '5', '5.1', '5.2',
'5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '6', '6.1', '6.2',
'6.3', '6.4', '6.5', '6.6', '6.7', '6.8', '6.9', '7', '7.1', '7.2',
'7.3', '7.4', '7.5', '7.6', '7.7', '7.8', '7.9', '8', '8.1', '8.2',
'8.3', '8.4', '8.5', '8.6', '8.7', '8.8', '8.9', '9', '9.1', '9.2',
'9.3', '9.4', '9.5', '9.6', '9.7', 'tbd', nan], dtype=object)
Aббревиатура 'tbd' в столбце с оценкой пользователей означает "будет определено" (to be determined). Скорее всего, это означает, что рейтинг ещё не был установлен или расчёт ещё не завершён. Это может быть связано с тем, что игра только что вышла или прошла недостаточное количество обзоров, чтобы для неё был установлен окончательный рейтинг.
Поскольку признак user_score принимает числовые значения, и значение 0 означает не отсутствие рейтинга, а его низкий уровень, заменим 'tbd' на значение-метку (−1). Таким образом, значение-метка является числовым, но не входит во множество допустимых значений признака и поэтому означает отсутствие значения рейтинга пользователей.
data['user_score'] = data['user_score'].replace('tbd', '-1')
data['user_score'].sort_values().unique()
array(['-1', '0', '0.2', '0.3', '0.5', '0.6', '0.7', '0.9', '1', '1.1',
'1.2', '1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '2', '2.1',
'2.2', '2.3', '2.4', '2.5', '2.6', '2.7', '2.8', '2.9', '3', '3.1',
'3.2', '3.3', '3.4', '3.5', '3.6', '3.7', '3.8', '3.9', '4', '4.1',
'4.2', '4.3', '4.4', '4.5', '4.6', '4.7', '4.8', '4.9', '5', '5.1',
'5.2', '5.3', '5.4', '5.5', '5.6', '5.7', '5.8', '5.9', '6', '6.1',
'6.2', '6.3', '6.4', '6.5', '6.6', '6.7', '6.8', '6.9', '7', '7.1',
'7.2', '7.3', '7.4', '7.5', '7.6', '7.7', '7.8', '7.9', '8', '8.1',
'8.2', '8.3', '8.4', '8.5', '8.6', '8.7', '8.8', '8.9', '9', '9.1',
'9.2', '9.3', '9.4', '9.5', '9.6', '9.7', nan], dtype=object)
Приведём наименования игр к нижнему регистру.
data['name'] = data['name'].str.lower()
data['name'].sample(7)
9407 wwe survivor series 4781 warriors orochi 2 (jp sales) 14816 dream girl premier 10366 naruto shippuden 3d: the new era 158 super smash bros. 13661 scaler 4565 command & conquer 3: tiberium wars Name: name, dtype: object
Приведём наименования платформ к нижнему регистру.
data['platform'] = data['platform'].str.lower()
data['platform'].sort_values().unique()
array(['2600', '3do', '3ds', 'dc', 'ds', 'gb', 'gba', 'gc', 'gen', 'gg',
'n64', 'nes', 'ng', 'pc', 'pcfx', 'ps', 'ps2', 'ps3', 'ps4', 'psp',
'psv', 'sat', 'scd', 'snes', 'tg16', 'wii', 'wiiu', 'ws', 'x360',
'xb', 'xone'], dtype=object)
Приведём наименования категорий рейтинга ESRB к нижнему регистру.
data['rating'] = data['rating'].str.lower()
data['rating'].sort_values().unique()
array(['ao', 'e', 'e10+', 'ec', 'k-a', 'm', 'rp', 't', nan], dtype=object)
Среди компьютерных игр есть такие, которые в своём названии содержат значение 'weekly sales'. Это уточнение сделано для тех игр, у которых отслеживался объём продаж, вероятно, за первую неделю после выхода игры на рынок.
data.loc[data['name'].str.contains('weekly'), 'name'].sort_values().head()
7837 chou-kuukan night pro yakyuu king (weekly jp s... 13665 fifa soccer 2003 (weekly jp sales) 8040 international superstar soccer 2000 (jp weekly... 10640 international superstar soccer 64 (weekly jp s... 13146 medal of honor: european assault (weekly jp sa... Name: name, dtype: object
Для этих же игр существует информация об общем объёме продаж по регионам за всё время, в котором учтён объём продаж за первую неделю.
data[data['name'].str.contains("fifa soccer 2003")].sort_values(by='name')
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 393 | fifa soccer 2003 | ps2 | 2002.0 | sports | 0.46 | 2.28 | 0.05 | 0.61 | 88.0 | 6.7 | e |
| 3183 | fifa soccer 2003 | xb | 2002.0 | sports | 0.20 | 0.40 | 0.00 | 0.04 | 88.0 | 7.7 | e |
| 11457 | fifa soccer 2003 | gc | 2002.0 | sports | 0.06 | 0.02 | 0.00 | 0.00 | 86.0 | 7.8 | e |
| 12917 | fifa soccer 2003 | gba | 2002.0 | sports | 0.04 | 0.01 | 0.00 | 0.00 | 76.0 | -1 | e |
| 13665 | fifa soccer 2003 (weekly jp sales) | ps2 | 2002.0 | sports | 0.00 | 0.00 | 0.04 | 0.00 | NaN | NaN | NaN |
Совершенно очевидно, что записи со значениями 'weekly sales' необходимо удалить.
data.drop(index=data.loc[data['name'].str.contains("weekly"), 'name'].index,
inplace=True)
data.loc[data['name'].str.contains("weekly"), 'name'].count()
0
Среди компьютерных игр есть ещё и такие, которые в своём названии содержат значение 'sales'. Это произошло от того, что информация о компьютерных играх внесена в набор данных вместе с информацией о продажах по регионам в форме отдельных записей.
data.loc[data['name'].str.contains('sales'), 'name'].sort_values().head()
8597 .hack//g.u. vol.2//reminisce (jp sales) 9249 ape escape academy (jp sales) 13825 atelier iris 3: grand phantasm (jp sales) 5979 atelier iris 3: grand phantasm (us sales) 15015 battlefield 2: modern combat(jp sales) Name: name, dtype: object
Необходимо удалить из названий компьютерных игр сведения о регионах продаж.
list_for_replace = [
'\(higher jp sales\)', '\(jp sales, but wrong system\)',
'\(old all region sales\)', '\(jp & incomplete us sales\)',
'\(american and others sales\)', '\(all regions sales\)',
'\(sales, but wrong system\)', '\(correct us sales\)',
'\(old us sales\)', '\(old jp sales\)', '\(jp & others sales\)',
'\(us & others sales\)', '\(japan sales\)', '\(all region sales\)',
'\(american sales\)', '\(jp sales\)', '\(us sales\)', '\(others sales\)'
]
for value in list_for_replace:
data.loc[data['name'].str.contains(value), 'name'] = \
data.loc[data['name'].str.contains(value), 'name'].str.replace(value, '').str.strip()
data.loc[data['name'].str.contains('sales'), 'name'].count()
0
Исправим ошибочные значения названий игр.
data.loc[data['name'] == 'brave story: new traveler', 'name'] = \
'brave story: new traveller'
data.loc[data['name'] == 'imagine figure skater', 'name'] = \
'imagine: figure skater'
data.loc[data['name'] == 'namco museum 50th anniversary', 'name'] = \
'namco museum: 50th anniversary'
data.loc[data['name'] == 'rengoku ii: the stairway to h.e.a.v.e.n.', 'name'] = \
'rengoku ii: the stairway to h.e.a.v.e.n.'
data.loc[data['name'] == 'dancedancerevolution ii', 'name'] = \
'dance dance revolution ii'
Исправим ошибочные значения названий жанров.
data.loc[(data['name'] == 'dance dance revolution: mario mix') &
(data['genre'] == 'simulation'), 'genre'] = 'misc'
data.loc[(data['name'] == 'dragon ball z: budokai tenkaichi 2') &
(data['genre'] == 'action'), 'genre'] = 'fighting'
data.loc[(data['name'] == 'dragon ball: origins') &
(data['genre'] == 'adventure'), 'genre'] = 'action'
data.loc[(data['name'] == 'earth defense force 2017') &
(data['genre'] == 'shooter'), 'genre'] = 'action'
data.loc[(data['name'] == 'fishing master') &
(data['genre'] == 'misc'), 'genre'] = 'sports'
data.loc[(data['name'] == 'prinny: can i really be the hero?') &
(data['genre'] == 'action'), 'genre'] = 'platform'
data.loc[(data['name'] == 'the godfather: blackhand edition') &
(data['genre'] == 'adventure'), 'genre'] = 'action'
data.loc[(data['name'] == 'tomb raider: underworld') &
(data['genre'] == 'adventure'), 'genre'] = 'action'
data.loc[(data['name'] == 'yu-gi-oh! the eternal duelist soul') &
(data['genre'] == 'misc'), 'genre'] = 'strategy'
data.loc[data['name'].str.contains('scrabble'), 'genre'] = 'puzzle'
data[(data['name'] == 'dance dance revolution: mario mix') |
(data['name'] == 'dragon ball z: budokai tenkaichi 2') |
(data['name'] == 'dragon ball: origins') |
(data['name'] == 'earth defense force 2017') |
(data['name'] == 'fishing master') |
(data['name'] == 'prinny: can i really be the hero?') |
(data['name'] == 'the godfather: blackhand edition') |
(data['name'] == 'tomb raider: underworld') |
(data['name'] == 'yu-gi-oh! the eternal duelist soul') |
data['name'].str.contains('scrabble')].sort_values(by='name')
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 12799 | dance dance revolution: mario mix | gc | 2005.0 | misc | 0.00 | 0.00 | 0.05 | 0.00 | NaN | NaN | NaN |
| 4203 | dance dance revolution: mario mix | gc | 2005.0 | misc | 0.36 | 0.09 | 0.00 | 0.01 | 69.0 | 8.4 | e |
| 2579 | dragon ball z: budokai tenkaichi 2 | ps2 | 2006.0 | fighting | 0.66 | 0.02 | 0.00 | 0.11 | 73.0 | 8.6 | t |
| 6100 | dragon ball z: budokai tenkaichi 2 | wii | 2006.0 | fighting | 0.24 | 0.03 | 0.00 | 0.02 | 72.0 | 8.5 | t |
| 5294 | dragon ball z: budokai tenkaichi 2 | wii | NaN | fighting | 0.15 | 0.05 | 0.14 | 0.01 | NaN | NaN | NaN |
| 9953 | dragon ball: origins | ds | 2008.0 | action | 0.08 | 0.02 | 0.00 | 0.01 | 78.0 | 7.5 | t |
| 7213 | dragon ball: origins | ds | 2008.0 | action | 0.04 | 0.00 | 0.17 | 0.00 | NaN | NaN | NaN |
| 15969 | earth defense force 2017 | x360 | 2006.0 | action | 0.00 | 0.00 | 0.02 | 0.00 | NaN | NaN | NaN |
| 11571 | earth defense force 2017 | x360 | 2006.0 | action | 0.04 | 0.00 | 0.03 | 0.00 | 69.0 | 7.7 | t |
| 12353 | fishing master | wii | 2007.0 | sports | 0.00 | 0.00 | 0.06 | 0.00 | NaN | NaN | NaN |
| 5707 | fishing master | wii | 2007.0 | sports | 0.29 | 0.00 | 0.00 | 0.02 | 58.0 | 8.1 | e |
| 10984 | prinny: can i really be the hero? | psp | 2008.0 | platform | 0.03 | 0.00 | 0.05 | 0.01 | 72.0 | 7 | t |
| 12568 | prinny: can i really be the hero? | psp | NaN | platform | 0.06 | 0.00 | 0.00 | 0.00 | NaN | NaN | NaN |
| 11088 | scrabble | psp | 2009.0 | puzzle | 0.08 | 0.00 | 0.00 | 0.01 | NaN | -1 | e |
| 6619 | scrabble | ps | 1999.0 | puzzle | 0.14 | 0.10 | 0.00 | 0.02 | NaN | NaN | NaN |
| 6643 | scrabble | ds | 2009.0 | puzzle | 0.20 | 0.02 | 0.00 | 0.03 | NaN | -1 | e |
| 6968 | scrabble | ds | 2009.0 | puzzle | 0.00 | 0.23 | 0.00 | 0.00 | NaN | NaN | NaN |
| 4116 | scrabble 2007 edition | ds | 2007.0 | puzzle | 0.00 | 0.47 | 0.00 | 0.00 | NaN | NaN | NaN |
| 12785 | scrabble blast! | gba | 2005.0 | puzzle | 0.04 | 0.01 | 0.00 | 0.00 | NaN | NaN | NaN |
| 6752 | sorry! / aggravation / scrabble junior | gba | 2005.0 | puzzle | 0.18 | 0.07 | 0.00 | 0.00 | NaN | NaN | NaN |
| 8743 | the godfather: blackhand edition | wii | 2007.0 | action | 0.14 | 0.00 | 0.00 | 0.01 | 77.0 | 8.5 | m |
| 8155 | tomb raider: underworld | ps2 | 2009.0 | action | 0.09 | 0.04 | 0.00 | 0.05 | NaN | 5.8 | t |
| 7862 | tomb raider: underworld | ds | 2008.0 | action | 0.15 | 0.02 | 0.00 | 0.01 | 70.0 | 8.4 | t |
| 6567 | tomb raider: underworld | ps2 | 2009.0 | action | 0.00 | 0.21 | 0.00 | 0.04 | NaN | NaN | NaN |
| 11589 | tomb raider: underworld | pc | 2008.0 | action | 0.00 | 0.06 | 0.00 | 0.01 | 80.0 | 7.7 | t |
| 4299 | tomb raider: underworld | wii | 2008.0 | action | 0.13 | 0.27 | 0.00 | 0.05 | 70.0 | 7.2 | t |
| 1924 | tomb raider: underworld | x360 | 2008.0 | action | 0.53 | 0.42 | 0.01 | 0.11 | 76.0 | 6.6 | t |
| 1579 | tomb raider: underworld | ps3 | 2008.0 | action | 0.45 | 0.55 | 0.05 | 0.22 | 75.0 | 7.2 | t |
| 4731 | yu-gi-oh! the eternal duelist soul | gba | 2001.0 | strategy | 0.00 | 0.00 | 0.40 | 0.01 | NaN | NaN | NaN |
| 815 | yu-gi-oh! the eternal duelist soul | gba | 2001.0 | strategy | 1.64 | 0.36 | 0.00 | 0.07 | NaN | NaN | NaN |
Среди записей набора данных есть одна, в которой платформа не соответствует году выпуска.
data[(data['platform'] == 'ds') & (data['year_of_release'] == 1985)]
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 15957 | strongest tokyo university shogi ds | ds | 1985.0 | action | 0.0 | 0.0 | 0.02 | 0.0 | NaN | NaN | NaN |
Поскольку установить название платформы для этой игры не представляется возможным, удалим запись.
data.drop(index=data[(data['platform'] == 'ds') &
(data['year_of_release'] == 1985)].index, inplace=True)
data[(data['platform'] == 'ds') & (data['year_of_release'] == 1985)].shape[0]
0
Кроме того, среди записей есть одна, в которой год выпуска платформы не соответствует платформе.
data[(data['platform'] == 'xb') & (data['year_of_release'] < 2001)]
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2076 | nfl fever 2002 | xb | 2000.0 | sports | 0.74 | 0.21 | 0.0 | 0.04 | 79.0 | 8.5 | e |
Поскольку платформа Xbox One появилась только в 2001 году, необходимо исправить ошибочное значение.
data.loc[(data['platform'] == 'xb') &
(data['year_of_release'] < 2001), 'year_of_release'] = 2001
len(data[(data['platform'] == 'xb') & (data['year_of_release'] < 2001)])
0
Поскольку категория K-A была заменена на категорию E, произведём и мы соответствующую замену.
data['rating'].replace('k-a', 'e', inplace=True)
data['rating'].sort_values().unique()
array(['ao', 'e', 'e10+', 'ec', 'm', 'rp', 't', nan], dtype=object)
Предварительно зададим функцию, выводящую таблицу с распределением пропущенных значений.
def show_na():
'''
Функция подсчёта пропущенных значений.
Возвращает таблицу распределения пропущенных значений,
отсортированную по убыванию значений.
'''
total = data.isna().sum().sort_values(ascending=False)
percent = (data.isna().sum() /
data.isna().count() * 100).round(1).sort_values(ascending=False)
display(pd.concat([total, percent], axis=1, keys=['Всего пропусков', '%']))
show_na()
| Всего пропусков | % | |
|---|---|---|
| critic_score | 8555 | 51.3 |
| rating | 6743 | 40.4 |
| user_score | 6678 | 40.0 |
| year_of_release | 268 | 1.6 |
| name | 0 | 0.0 |
| platform | 0 | 0.0 |
| genre | 0 | 0.0 |
| na_sales | 0 | 0.0 |
| eu_sales | 0 | 0.0 |
| jp_sales | 0 | 0.0 |
| other_sales | 0 | 0.0 |
Среди значений признака year_of_release 268 пропуска. Вероятно, эти данные были потеряны в результате технической ошибки при извлечении или копировании данных.
Составим словарь с годами выпуска для тех игр, для которых есть пропуски в значениях признака year_of_release. Данные возьмём из открытых источников.
years_of_release = {
"prinny: can i really be the hero?": 2008,
"dragon ball z: budokai tenkaichi 2": 2006,
"yu-gi-oh! 5d's wheelie breakers": 2009,
'luminous arc 2': 2008,
"cabela's alaskan adventure": 2006,
'samurai spirits: tenkaichi kenkakuden': 2006,
'sega rally 2006': 2006,
'mountain bike adrenaline': 2007,
"mcfarlane's evil prophecy": 2004,
'demon chaos': 2005,
'star trek: conquest': 2007,
'saru! get you! million monkeys': 2006,
'ejay clubworld': 2002,
'sword of the samurai': 2003,
"james cameron's dark angel": 2002,
'nba starting five': 2002,
'yu yu hakusho: dark tournament': 2004,
'tribes: aerial assault': 2002,
'jet x20': 2002,
'mega man x collection': 2006,
'college hoops 2k6': 2005,
'haven: call of the king': 2002,
'final fantasy xi': 2002,
'harvest moon: save the homeland': 2001,
'nfl gameday 2003': 2002,
'nascar: dirt to daytona': 2002,
'monster hunter 2': 2006,
'mlb slugfest 20-03': 2002,
'wheel of fortune': 2003,
'suikoden iii': 2002,
'nascar thunder 2003': 2002,
'wwe smackdown vs. raw 2006': 2005,
'fifa soccer 2004': 2003,
'madden nfl 2004': 2003,
'ferrari: the race experience': 2010,
"dance! it's your stage": 2010,
'saint': 2009,
'wii de asobu: metroid prime': 2009,
'combat wings: the great battles of wwii': 2012,
'swords': 2010,
"luxor: pharaoh's challenge": 2008,
'reader rabbit 2nd grade': 2011,
"flip's twisted world": 2010,
'build-a-bear workshop: friendship valley': 2010,
'zero: tsukihami no kamen': 2008,
"disney's chicken little: ace in action": 2006,
'our house party!': 2009,
'vegas party': 2009,
'trauma team': 2010,
'dance dance revolution ii': 2011,
'big beach sports 2': 2010,
"tony hawk's downhill jam": 2006,
'nhl slapshot': 2010,
'tiger woods pga tour 07': 2006,
'madden nfl 11': 2010,
'rhythm heaven': 2011,
'call of duty 3': 2006,
'lego indiana jones: the original adventures': 2008,
'brothers in arms: furious 4': 2015,
'akb1/48: idol to guam de koishitara...': 2011,
'football manager 2007': 2006,
'world of tanks': 2014,
'majesty 2: the fantasy kingdom sim': 2009,
'tour de france 2011': 2011,
'mobile ops: the one year war': 2008,
'national geographic challenge!': 2011,
'yoostar on mtv': 2011,
'get fit with mel b': 2010,
'jurassic park: the game': 2011,
'otomedius excellent': 2011,
'star trek: legacy': 2006,
'gun': 2005,
'tropico 4': 2011,
'wet': 2009,
'madden nfl 06': 2005,
'shaun white snowboarding': 2008,
'shorts': 2009,
'dream dancer': 2009,
'jet impulse': 2007,
'pdc world championship darts 2008': 2008,
"shonen jump's yu-gi-oh! gx card almanac": 2007,
'writing and speaking beautiful japanese ds': 2007,
'runaway: a twist of fate': 2009,
'steal princess': 2008,
'legacy of ys: books i & ii': 2009,
'bikkuriman daijiten': 2007,
'housekeeping': 2010,
'captain america: super soldier': 2011,
'jewel link chronicles: mountains of madness': 2012,
'chou soujuu mecha mg': 2006,
'alex rider: stormbreaker': 2006,
'tornado': 2008,
'mega man battle network: operation shooting star': 2009,
'charm girls club: my fashion show': 2009,
'egg monster hero': 2005,
'my healthy cooking coach': 2009,
'atsumare! power pro kun no ds koushien': 2006,
'the daring game for girls': 2009,
'charm girls club: my fashion mall': 2009,
'shrek the third': 2007,
'advance wars: days of ruin': 2008,
'hakuouki: shinsengumi kitan': 2008,
'agarest senki: re-appearance': 2008,
'umineko no naku koro ni san: shinjitsu to gensou no yasoukyoku': 2011,
'the history channel: great battles - medieval': 2010,
'monster hunter frontier online': 2007,
'port royale 3': 2012,
'happy feet two': 2011,
'record of agarest war zero': 2009,
'bejeweled 3': 2010,
'splatterhouse': 2010,
'backbreaker': 2010,
'wrc: fia world rally championship': 2010,
'move fitness': 2011,
'singularity': 2010,
'jonah lomu rugby challenge': 2011,
'rock revolution': 2008,
'silent hill: homecoming': 2008,
"robert ludlum's the bourne conspiracy": 2008,
'sonic the hedgehog': 2006,
'test drive unlimited 2': 2011,
'the lord of the rings: war in the north': 2011,
'yakuza 4': 2010,
'rock band': 2007,
'aquaman: battle for atlantis': 2003,
'without warning': 2005,
'the king of fighters: maximum impact - maniax': 2005,
'tom and jerry in war of the whiskers': 2002,
'combat elite: wwii paratroopers': 2005,
"tom clancy's rainbow six: critical hour": 2006,
'rayman arena': 2001,
'drake of the 99 dragons': 2003,
'godzilla: destroy all monsters melee': 2002,
'transworld surf': 2001,
'all-star baseball 2005': 2004,
'robotech: battlecry': 2002,
'unreal championship 2: the liandri conflict': 2005,
'star wars jedi knight ii: jedi outcast': 2002,
'the chronicles of riddick: escape from butcher bay': 2004,
'def jam: fight for ny': 2004,
'madden nfl 2002': 2001,
'metal gear solid 2: substance': 2002,
'namco museum': 2001,
'hitman 2: silent assassin': 2002,
'home run': 1978,
'breakaway iv': 1978,
'ghostbusters ii': 1989,
'flag capture': 1978,
'indy 500': 1977,
'slot machine': 1979,
'dragster': 1980,
'hangman': 1978,
'super breakout': 1978,
"maze craze: a game of cops 'n robbers": 1980,
'circus atari': 1977,
'karate': 1982,
'fishing derby': 1980,
'air-sea battle': 1977,
'combat': 1977,
'adventure': 1979,
'space invaders': 1980,
'inversion': 2012,
'homeworld remastered collection': 2015,
'wrc: fia world rally championship': 2010,
'battle vs. chess': 2011,
'grid': 2008,
'clockwork empires': 2016,
'rollercoaster tycoon': 1999,
'dead island: riptide': 2013,
'rocksmith': 2011,
'street fighter iv': 2008,
'test drive unlimited 2': 2011,
'dead space 3': 2013,
'bioshock 2': 2010,
'tomb raider (2013)': 2013,
'tera': 2011,
'call of duty: black ops': 2010,
'pdc world championship darts 2008': 2008,
'payout poker & casino': 2006,
'fullmetal alchemist: brotherhood': 2010,
'major league baseball 2k8': 2008,
'half-minute hero 2': 2011,
'samurai shodown anthology': 2008,
'major league baseball 2k6': 2006,
'super robot wars og saga: masou kishin ii - revelation of evil god': 2012,
'valkyria chronicles iii: unrecorded chronicles': 2011,
'danganronpa: trigger happy havoc': 2010,
'the golden compass': 2007,
'pes 2009: pro evolution soccer': 2008,
'madden nfl 07': 2006,
'lego batman: the videogame': 2008,
'disgaea 3: absence of detention': 2011,
'donkey kong land iii': 1997,
'custom robo': 1999,
'famista 64': 1997,
'wcw backstage assault': 2000,
'triple play 99': 1998,
'legacy of kain: soul reaver': 1999,
'the dukes of hazzard ii: daisy dukes it out': 2000,
'twisted metal: small brawl': 2001,
'alone in the dark: the new nightmare': 2001,
'action man-operation extreme': 2000,
'b.l.u.e.: legend of water': 1998,
'lego harry potter: years 5-7': 2011,
'harvest moon: the tale of two towns': 2011,
'pet zombies': 2011,
'face racers: photo finish': 2011,
'the hidden': 2011,
'dream trigger 3d': 2011,
'beyond the labyrinth': 2012,
'mario tennis': 2012,
"frogger's adventures: temple of the frog": 2001,
'warioware: twisted!': 2004,
'the chronicles of narnia: the lion, the witch and the wardrobe': 2005,
"cubix robots for everyone: clash 'n' bash": 2002,
'teen titans': 2005,
"disney's cinderella: magical dreams": 2005,
'super puzzle fighter ii': 2003,
'drill dozer': 2005,
'sabre wulf': 2004,
'super duper sumos': 2003,
'nba street vol. 2': 2003,
'nba live 2003': 2002,
'nicktoons: battle for volcano island': 2006,
'pac-man fever': 2002,
'nintendo puzzle collection': 2003,
'street hoops': 2002,
'giftpia': 2003,
'smashing drive': 2002,
'nhl hitz pro': 2003,
'tube slider': 2003,
'dinotopia: the sunstone odyssey': 2003,
'freaky flyers': 2003,
'virtua quest': 2004
}
Заполним пропущенные значения признака year_of_release значениями из словаря.
for value in years_of_release:
data.loc[data['name'] == value, 'year_of_release'] = \
data.loc[data['name'] == value, 'year_of_release'].fillna(years_of_release.get(value))
data['year_of_release'].sort_values().unique()
array([1977., 1978., 1979., 1980., 1981., 1982., 1983., 1984., 1985.,
1986., 1987., 1988., 1989., 1990., 1991., 1992., 1993., 1994.,
1995., 1996., 1997., 1998., 1999., 2000., 2001., 2002., 2003.,
2004., 2005., 2006., 2007., 2008., 2009., 2010., 2011., 2012.,
2013., 2014., 2015., 2016.])
show_na()
| Всего пропусков | % | |
|---|---|---|
| critic_score | 8555 | 51.3 |
| rating | 6743 | 40.4 |
| user_score | 6678 | 40.0 |
| name | 0 | 0.0 |
| platform | 0 | 0.0 |
| year_of_release | 0 | 0.0 |
| genre | 0 | 0.0 |
| na_sales | 0 | 0.0 |
| eu_sales | 0 | 0.0 |
| jp_sales | 0 | 0.0 |
| other_sales | 0 | 0.0 |
Поскольку признак user_score принимает числовые значения, то тип данных необходимо изменить с object на float64.
data['user_score'] = pd.to_numeric(data['user_score'])
data['user_score'].dtypes
dtype('float64')
Поскольку признак year_of_release принимает целочисленные значения, то тип данных необходимо изменить с float64 на int64.
data['year_of_release'] = data['year_of_release'].astype('int64')
data['year_of_release'].dtypes
dtype('int64')
Полные дубликаты в наборе данных отсутствуют.
data.duplicated().sum()
0
Поскольку в названиях компьютерных игр были удалены сведения о регионах продаж, это могло привести к появлению частичных дубликатов.
Основными сведениями для проверки на наличие частичных дубликатов являются значения признаков name, platform и year_of_release, позволяющие однозначно идентифицировать компьютерную игру.
loc_data = data[
data[['name', 'platform', 'year_of_release']].duplicated(keep=False)
].sort_values(by='name')
loc_data.head(10)
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 7087 | .hack//g.u. vol.2//reminisce | ps2 | 2006 | role-playing | 0.11 | 0.09 | 0.00 | 0.03 | NaN | NaN | NaN |
| 8597 | .hack//g.u. vol.2//reminisce | ps2 | 2006 | role-playing | 0.00 | 0.00 | 0.16 | 0.00 | NaN | NaN | NaN |
| 5455 | ape escape academy | psp | 2004 | misc | 0.13 | 0.15 | 0.00 | 0.05 | 51.0 | 5.8 | e10+ |
| 9249 | ape escape academy | psp | 2004 | misc | 0.00 | 0.00 | 0.13 | 0.00 | NaN | NaN | NaN |
| 5979 | atelier iris 3: grand phantasm | ps2 | 2006 | role-playing | 0.14 | 0.11 | 0.00 | 0.04 | NaN | NaN | NaN |
| 13825 | atelier iris 3: grand phantasm | ps2 | 2006 | role-playing | 0.00 | 0.00 | 0.04 | 0.00 | NaN | NaN | NaN |
| 4400 | battlefield 2: modern combat | ps2 | 2005 | shooter | 0.37 | 0.01 | 0.00 | 0.06 | 80.0 | 8.5 | t |
| 15015 | battlefield 2: modern combat | ps2 | 2005 | shooter | 0.00 | 0.00 | 0.02 | 0.00 | NaN | NaN | NaN |
| 8805 | bleach: dark souls | ds | 2007 | fighting | 0.12 | 0.02 | 0.00 | 0.01 | 82.0 | 7.9 | t |
| 10670 | bleach: dark souls | ds | 2007 | fighting | 0.00 | 0.00 | 0.10 | 0.00 | NaN | NaN | NaN |
Таким образом, всего кандидатов в дубли — 198.
Создадим вспомогательный набор данных, в котором просуммируем объёмы продаж каждой игры для каждой платформы, выпущенной за каждый год.
columns = ['name', 'platform', 'year_of_release', 'genre']
data2 = data[
data[columns].duplicated(keep=False)
].groupby(columns)[['na_sales', 'eu_sales', 'jp_sales', 'other_sales']].agg('sum').reset_index()
data2.head()
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | |
|---|---|---|---|---|---|---|---|---|
| 0 | .hack//g.u. vol.2//reminisce | ps2 | 2006 | role-playing | 0.11 | 0.09 | 0.16 | 0.03 |
| 1 | ape escape academy | psp | 2004 | misc | 0.13 | 0.15 | 0.13 | 0.05 |
| 2 | atelier iris 3: grand phantasm | ps2 | 2006 | role-playing | 0.14 | 0.11 | 0.04 | 0.04 |
| 3 | battlefield 2: modern combat | ps2 | 2005 | shooter | 0.37 | 0.01 | 0.02 | 0.06 |
| 4 | bleach: dark souls | ds | 2007 | fighting | 0.12 | 0.02 | 0.10 | 0.01 |
Передадим известные значения рейтинга для записей во вспомогательном наборе данных.
for column in ['critic_score', 'user_score', 'rating']:
for game_name in (loc_data.loc[loc_data[column].notna(), 'name'].unique()):
for platform_name in (loc_data.loc[loc_data[column].notna() &
(loc_data['name'] == game_name),
'platform']).unique():
set_score = pd.Series(loc_data.loc[loc_data[column].notna() &
(loc_data['name'] == game_name) &
(loc_data['platform'] == platform_name),
column]).reset_index(drop=True)
data2.loc[(data2['name'] == game_name) &
(data2['platform'] == platform_name),
column] = set_score[0]
data2.head()
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | .hack//g.u. vol.2//reminisce | ps2 | 2006 | role-playing | 0.11 | 0.09 | 0.16 | 0.03 | NaN | NaN | NaN |
| 1 | ape escape academy | psp | 2004 | misc | 0.13 | 0.15 | 0.13 | 0.05 | 51.0 | 5.8 | e10+ |
| 2 | atelier iris 3: grand phantasm | ps2 | 2006 | role-playing | 0.14 | 0.11 | 0.04 | 0.04 | NaN | NaN | NaN |
| 3 | battlefield 2: modern combat | ps2 | 2005 | shooter | 0.37 | 0.01 | 0.02 | 0.06 | 80.0 | 8.5 | t |
| 4 | bleach: dark souls | ds | 2007 | fighting | 0.12 | 0.02 | 0.10 | 0.01 | 82.0 | 7.9 | t |
data2['critic_score'].sort_values().unique()
array([43., 46., 48., 50., 51., 52., 57., 58., 60., 61., 62., 64., 65.,
66., 67., 68., 69., 70., 71., 72., 73., 75., 77., 78., 79., 80.,
82., 83., 86., 87., nan])
data2['user_score'].sort_values().unique()
array([-1. , 4.1, 4.4, 4.6, 5.4, 5.5, 5.7, 5.8, 5.9, 6.2, 6.5,
6.6, 6.8, 6.9, 7. , 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8,
7.9, 8. , 8.1, 8.2, 8.3, 8.4, 8.5, 8.7, 8.9, 9. , nan])
data2['rating'].sort_values().unique()
array(['e', 'e10+', 'm', 't', nan], dtype=object)
Удалим из основного набора данных дублирующиеся записи.
data.shape[0]
16692
data.drop(
index=data[data[['name', 'platform', 'year_of_release']].duplicated(keep=False)].index,
inplace=True
)
len(data[data[['name', 'platform', 'year_of_release']].duplicated(keep=False)])
0
data.shape[0]
16494
Добавим к основному набору данных записи из вспомогательного набора данных.
data = pd.concat([data, data2])
data.shape[0]
16593
show_na()
| Всего пропусков | % | |
|---|---|---|
| critic_score | 8458 | 51.0 |
| rating | 6646 | 40.1 |
| user_score | 6581 | 39.7 |
| name | 0 | 0.0 |
| platform | 0 | 0.0 |
| year_of_release | 0 | 0.0 |
| genre | 0 | 0.0 |
| na_sales | 0 | 0.0 |
| eu_sales | 0 | 0.0 |
| jp_sales | 0 | 0.0 |
| other_sales | 0 | 0.0 |
Пропуски в значениях признаков critic_score и user_score заполним значением-меткой (−1).
Пропуски в этих признаках возникли из-за того, что в открытом источнике данных отсутствовали оценки для некоторых игр. Вероятно, оценки были собраны в определённых регионах распространения игр, в то время как некоторые игры распространялись только в других регионах мира.
data['critic_score'].fillna(-1, inplace=True)
data['user_score'].fillna(-1, inplace=True)
data['critic_score'].sort_values().unique()
array([-1., 13., 17., 19., 20., 21., 22., 23., 24., 25., 26., 27., 28.,
29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41.,
42., 43., 44., 45., 46., 47., 48., 49., 50., 51., 52., 53., 54.,
55., 56., 57., 58., 59., 60., 61., 62., 63., 64., 65., 66., 67.,
68., 69., 70., 71., 72., 73., 74., 75., 76., 77., 78., 79., 80.,
81., 82., 83., 84., 85., 86., 87., 88., 89., 90., 91., 92., 93.,
94., 95., 96., 97., 98.])
data['user_score'].sort_values().unique()
array([-1. , 0. , 0.2, 0.3, 0.5, 0.6, 0.7, 0.9, 1. , 1.1, 1.2,
1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2. , 2.1, 2.2, 2.3,
2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3. , 3.1, 3.2, 3.3, 3.4,
3.5, 3.6, 3.7, 3.8, 3.9, 4. , 4.1, 4.2, 4.3, 4.4, 4.5,
4.6, 4.7, 4.8, 4.9, 5. , 5.1, 5.2, 5.3, 5.4, 5.5, 5.6,
5.7, 5.8, 5.9, 6. , 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7,
6.8, 6.9, 7. , 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8,
7.9, 8. , 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9,
9. , 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7])
Пропуски в значениях признака rating заполним значением-меткой 'nd' (no data).
Пропуски в этом признаке могли возникнуть из-за того, что во первых, организация ESRB ведёт свою деятельность с 1994 года, и некоторые игры, вышедшие на рынок раньше, не прошли процедуру присвоения рейтинга. Во-вторых, ESRB ведёт свою деятельность на территории США, и некоторые игры, которые распространялись только на территории других регионов и не попали на территорию США, могли не попасть в "поле зрения" организации. Поэтому для них не была проведена оценка.
data['rating'].fillna('nd', inplace=True)
data['rating'].sort_values().unique()
array(['ao', 'e', 'e10+', 'ec', 'm', 'nd', 'rp', 't'], dtype=object)
show_na()
| Всего пропусков | % | |
|---|---|---|
| name | 0 | 0.0 |
| platform | 0 | 0.0 |
| year_of_release | 0 | 0.0 |
| genre | 0 | 0.0 |
| na_sales | 0 | 0.0 |
| eu_sales | 0 | 0.0 |
| jp_sales | 0 | 0.0 |
| other_sales | 0 | 0.0 |
| critic_score | 0 | 0.0 |
| user_score | 0 | 0.0 |
| rating | 0 | 0.0 |
Рассчитаем общий (мировой) объём продаж для каждой игры. Создадим признак total_sales.
data['total_sales'] = data.loc[:,['na_sales','eu_sales', 'jp_sales', 'other_sales']].sum(axis=1)
Проверим, согласованы ли значения объёмов продаж.
data[['na_sales', 'eu_sales', 'jp_sales', 'other_sales', 'total_sales']].sample(7)
| na_sales | eu_sales | jp_sales | other_sales | total_sales | |
|---|---|---|---|---|---|
| 4597 | 0.35 | 0.05 | 0.00 | 0.02 | 0.42 |
| 8478 | 0.12 | 0.03 | 0.00 | 0.01 | 0.16 |
| 13566 | 0.03 | 0.01 | 0.00 | 0.00 | 0.04 |
| 3009 | 0.00 | 0.00 | 0.67 | 0.00 | 0.67 |
| 4125 | 0.23 | 0.18 | 0.00 | 0.06 | 0.47 |
| 7664 | 0.00 | 0.00 | 0.20 | 0.00 | 0.20 |
| 12251 | 0.00 | 0.00 | 0.07 | 0.00 | 0.07 |
Проверим, нет ли среди них игр с нулевым объёмом продаж в мире.
data[data['total_sales'] == 0]
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | total_sales | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 16676 | g1 jockey 4 2008 | ps3 | 2008 | sports | 0.0 | 0.0 | 0.0 | 0.0 | -1.0 | -1.0 | nd | 0.0 |
| 16709 | score international baja 1000: the official game | ps2 | 2008 | racing | 0.0 | 0.0 | 0.0 | 0.0 | -1.0 | -1.0 | nd | 0.0 |
Удалим записи с отсутствующими данными о продажах.
data.drop(index=data[data['total_sales'] == 0].index, inplace=True)
data[data['total_sales'] == 0].shape[0]
0
Сопоставим каждой категории рейтинга ESRB минимальный возраст пользователя. Создадим признак age (возрастные категории).
Если нет данных о том, какая категория рейтинга присвоена игре (т. е. значение рейтинга — 'nd'), то в качестве возраста укажем значение-метку (−1).
Играм, которым ещё не присвоена постоянная категория, но которые проходят оценку (т. е. значение рейтинга — 'rp'), сопоставим значение-метку 100. Она, с одной стороны, является таким же положительным числом как и любой возраст, но с другой стороны является "ограничителем" минимального возраста и, таким образом, индикатором.
def set_age(value):
if value == 'e':
return 0
if value == 'ec':
return 3
if value == 'e10+':
return 10
if value == 't':
return 13
if value == 'm':
return 17
if value == 'ao':
return 18
if value == 'rp':
return 100
if value == 'nd':
return -1
data['age'] = data['rating'].apply(set_age)
data['age'].sort_values().unique()
array([ -1, 0, 3, 10, 13, 17, 18, 100])
Проверим, согласованы ли значения признаков rating и age.
data[['rating', 'age']].sample(7)
| rating | age | |
|---|---|---|
| 15493 | nd | -1 |
| 3411 | nd | -1 |
| 15968 | nd | -1 |
| 9674 | m | 17 |
| 9016 | t | 13 |
| 12530 | e | 0 |
| 5706 | nd | -1 |
В соответствии с названием приставки введём категории поколений игровых систем. Для персональных компьютеров введём деление на поколения в соответствии с годами. Создадим признак generation.
def set_generation(value, year):
if value in ['2600']:
return 2
if value in ['nes']:
return 3
if value in ['gb', 'gg', 'gen', 'snes', 'ng', 'scd', 'tg16']:
return 4
if value in ['3do', 'n64', 'pcfx', 'ps', 'sat', 'ws']:
return 5
if value in ['dc', 'gba', 'gc', 'ps2', 'xb']:
return 6
if value in ['ds', 'ps3', 'psp', 'wii', 'x360']:
return 7
if value in ['3ds', 'ps4', 'psv', 'wiiu', 'xone']:
return 8
if value in ['pc']:
if year > 2011:
return 8
if 2003 < year <= 2011:
return 7
if 1997 < year <= 2003:
return 6
if 1993 < year <= 1997:
return 5
if 1986 < year <= 1993:
return 4
if 1982 < year <= 1986:
return 3
if year <= 1982:
return 2
data['generation'] = \
data[['platform', 'year_of_release']].apply(lambda x: set_generation(*x), axis=1)
data['generation'].sort_values().unique()
array([2, 3, 4, 5, 6, 7, 8])
Добавим сведения о производителе платформы для компьютерных игр. Создадим признак producer.
Для платформы "персональный компьютер" оставим значение 'pc', поскольку установить для таких записей производителя не представляется возможным.
def set_producer(value):
if value in ['2600']:
return 'atari'
if value in ['nes', 'gb', 'snes', 'n64', 'gba', 'gc', 'ds', 'wii', '3ds', 'wiiu']:
return 'nintendo'
if value in ['gen', 'scd', 'sat', 'dc', 'gg']:
return 'sega'
if value in ['ng']:
return 'snk'
if value in ['tg16', 'pcfx']:
return 'nec'
if value in ['3do']:
return 'panasonic'
if value in ['ps', 'ps2', 'ps3', 'psp', 'ps4', 'psv']:
return 'sony'
if value in ['ws']:
return 'bandai'
if value in ['xb', 'x360', 'xone']:
return 'microsoft'
if value in ['pc']:
return 'pc'
data['producer'] = data['platform'].apply(set_producer)
data['producer'].sort_values().unique()
array(['atari', 'bandai', 'microsoft', 'nec', 'nintendo', 'panasonic',
'pc', 'sega', 'snk', 'sony'], dtype=object)
Последние приготовления.
Отсортируем записи по значению года выпуска игры в хронологическом порядке и проиндексируем записи непрерывным рядом значений.
data = data.sort_values(by='year_of_release').reset_index(drop=True)
data.head()
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | total_sales | age | generation | producer | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | indy 500 | 2600 | 1977 | racing | 0.26 | 0.01 | 0.0 | 0.00 | -1.0 | -1.0 | nd | 0.27 | -1 | 2 | atari |
| 1 | combat | 2600 | 1977 | action | 1.17 | 0.07 | 0.0 | 0.01 | -1.0 | -1.0 | nd | 1.25 | -1 | 2 | atari |
| 2 | circus atari | 2600 | 1977 | action | 0.43 | 0.03 | 0.0 | 0.00 | -1.0 | -1.0 | nd | 0.46 | -1 | 2 | atari |
| 3 | air-sea battle | 2600 | 1977 | shooter | 0.91 | 0.06 | 0.0 | 0.01 | -1.0 | -1.0 | nd | 0.98 | -1 | 2 | atari |
| 4 | breakaway iv | 2600 | 1978 | puzzle | 0.20 | 0.01 | 0.0 | 0.00 | -1.0 | -1.0 | nd | 0.21 | -1 | 2 | atari |
data.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 16591 entries, 0 to 16590 Data columns (total 15 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 name 16591 non-null object 1 platform 16591 non-null object 2 year_of_release 16591 non-null int64 3 genre 16591 non-null object 4 na_sales 16591 non-null float64 5 eu_sales 16591 non-null float64 6 jp_sales 16591 non-null float64 7 other_sales 16591 non-null float64 8 critic_score 16591 non-null float64 9 user_score 16591 non-null float64 10 rating 16591 non-null object 11 total_sales 16591 non-null float64 12 age 16591 non-null int64 13 generation 16591 non-null int64 14 producer 16591 non-null object dtypes: float64(7), int64(3), object(5) memory usage: 1.9+ MB
Промежуточный вывод
Предварительно зададим функцию, рассчитывающую описательные статистики.
def descriptive_statistics(values, label):
'''
Описательная статистика переменной, измеряемой в количественной шкале.
Принимает значения признака и название признака.
Возвращает DataFrame с набором статистик.
'''
df = pd.DataFrame([
values.count(),
len(values.unique()),
values.min(),
values.median() - 1.5 * (values.quantile(q=.75) -
values.quantile(q=.25)),
values.quantile(q=.25).round(2),
(values.mode()).to_list(),
values.median().round(2),
values.mean().round(2),
values.quantile(q=.75).round(2),
values.median() + 1.5 * (values.quantile(q=.75) -
values.quantile(q=.25)),
values.max(),
values.max() - values.min(),
values.quantile(q=.75) - values.quantile(q=.25)
],
index=['кол-во значений', 'кол-во уникальных', 'мин.',
'-1.5IQR', '25 %', 'мода', 'медиана',
'среднее ариф.', '75 %', '+1.5IQR', 'макс.',
'размах', 'межквартильный размах'],
columns=[label])
return df
Описательная статистика.
pd.DataFrame(data['name'].describe()).rename(
index={'count': 'кол-во значений',
'unique': 'кол-во уникальных',
'top': 'мода',
'freq': 'частота моды'},
columns={'name': 'Название игры'})
| Название игры | |
|---|---|
| кол-во значений | 16591 |
| кол-во уникальных | 11431 |
| мода | need for speed: most wanted |
| частота моды | 12 |
Диаграмма размаха.
data['name'].value_counts().plot.box(
title='Диаграмма размаха\nрапределения количества упоминаний\nназвания игры',
label='Название игры',
ylabel='Частота упоминаний',
yticks=[2 * n + 1 for n in range(6)],
figsize=(3, 3))
plt.show()
Круговая диаграмма распределения игр по количеству упоминаний в наборе данных.
(data['name'].value_counts() > 1).value_counts().rename(
index={0: '1', 1: '2+'}).plot.pie(
title='Круговая диаграмма\nраспределения игр\nпо количеству упоминаний',
label='', figsize=(10, 3))
plt.show()
Таблица относительных частот.
pd.DataFrame((data['name'].value_counts() > 1).value_counts() /
len(data['name'].unique()) * 100).round(0).astype('int').rename(
index={0: '1 раз', 1: '2 и более раз'},
columns={'name': 'Относительная частота, %'}).T
| 1 раз | 2 и более раз | |
|---|---|---|
| Относительная частота, % | 75 | 25 |
Диаграмма распределения частот.
data['name'].value_counts().value_counts().plot.bar(
title='Диаграмма распределения количества упоминаний названия игры',
xlabel='Количество упоминаний названия игры',
ylabel='Количество игр',
rot=0, figsize=(10, 3))
plt.show()
Таблица частоты встречаемости наименований компьютерных игр.
pd.DataFrame(
data['name'].value_counts().value_counts()
).T.rename(index={'name': 'количество игр'})
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | |
|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 8624 | 1521 | 720 | 278 | 151 | 87 | 32 | 13 | 4 | 1 |
Таблица распределения частот (топ-5).
pd.DataFrame(
data['name'].value_counts().head()
).rename(columns={'name': 'частота'})
| частота | |
|---|---|
| need for speed: most wanted | 12 |
| madden nfl 07 | 9 |
| ratatouille | 9 |
| fifa 14 | 9 |
| lego marvel super heroes | 9 |
Описательная статистика.
descriptive_statistics(data['year_of_release'], 'Год выпуска')
| Год выпуска | |
|---|---|
| кол-во значений | 16591 |
| кол-во уникальных | 40 |
| мин. | 1977 |
| -1.5IQR | 1996.5 |
| 25 % | 2003.0 |
| мода | [2009] |
| медиана | 2007.0 |
| среднее ариф. | 2006.47 |
| 75 % | 2010.0 |
| +1.5IQR | 2017.5 |
| макс. | 2016 |
| размах | 39 |
| межквартильный размах | 7.0 |
Диаграмма размаха.
data['year_of_release'].value_counts().plot.box(
title='Диаграмма размаха\nраспределения количества игр,\nвыпускаемых в год',
label='Год выпуска',
ylabel='Количество игр в год',
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data['year_of_release'].value_counts().sort_index().plot.bar(
rot=0,
title='Диаграмма распределения игр по году выпуска',
xlabel='Год выпуска',
ylabel='Частота',
figsize=(10, 3))
plt.xticks([3, 8, 13, 18, 23, 28, 33, 38])
plt.show()
Таблица распределения частот (топ-10).
pd.DataFrame(data['year_of_release'].value_counts()).head(10).sort_index().T.rename(
index={'year_of_release': 'количество игр'})
| 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | |
|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 848 | 786 | 768 | 936 | 997 | 1193 | 1432 | 1437 | 1283 | 1179 |
Описательная статистика.
pd.DataFrame(data['platform'].describe()).rename(
index={'count': 'кол-во значений',
'unique': 'кол-во уникальных',
'top': 'мода',
'freq': 'частота моды'},
columns={'platform': 'Название платформы'})
| Название платформы | |
|---|---|
| кол-во значений | 16591 |
| кол-во уникальных | 31 |
| мода | ps2 |
| частота моды | 2128 |
Диаграмма размаха.
data['platform'].value_counts().plot.box(
title='Диаграмма размаха\nраспределения частоты\nвстречаемости платформ',
label='Платформа',
ylabel='Количество игр\nдля платформы',
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data['platform'].value_counts().plot.bar(
rot=0,
title='Диаграмма распределения игр по платформам',
xlabel='Название платформы',
ylabel='Частота',
figsize=(12, 3))
plt.show()
Таблица распределения частот (топ-10).
df = pd.DataFrame(data['platform'].value_counts()).head(10).T.join(
pd.DataFrame(pd.DataFrame(data['platform'].value_counts().head(10)).sum()))
df.rename(index={'platform': 'количество игр'}, columns={0: 'всего'})
| ps2 | ds | ps3 | wii | x360 | ps | psp | pc | xb | gba | всего | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 2128 | 2115 | 1327 | 1312 | 1256 | 1196 | 1192 | 974 | 820 | 817 | 13137 |
Описательная статистика.
descriptive_statistics(data['generation'], 'Поколения игровых систем')
| Поколения игровых систем | |
|---|---|
| кол-во значений | 16591 |
| кол-во уникальных | 7 |
| мин. | 2 |
| -1.5IQR | 5.5 |
| 25 % | 6.0 |
| мода | [7] |
| медиана | 7.0 |
| среднее ариф. | 6.51 |
| 75 % | 7.0 |
| +1.5IQR | 8.5 |
| макс. | 8 |
| размах | 6 |
| межквартильный размах | 1.0 |
Диаграмма размаха.
data['generation'].plot.box(
title='Диаграмма размаха\nраспределения игр\nпо номеру поколения игровых систем',
label='Название игры',
ylabel='Поколение игровых систем',
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data['generation'].value_counts().sort_index().plot.bar(
rot=0,
title='Диаграмма распределения игр\nпо номеру поколения игровых систем',
xlabel='Поколение игровых систем',
ylabel='Частота',
figsize=(6, 3))
plt.show()
Таблица распределения частот.
pd.DataFrame(data['generation'].value_counts().sort_index()).T.rename(
index={'generation': 'количество игр'})
| 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
|---|---|---|---|---|---|---|---|
| количество игр | 133 | 99 | 389 | 1712 | 4461 | 7805 | 1992 |
Описательная статистика.
pd.DataFrame(data['producer'].describe()).rename(
index={'count': 'кол-во значений',
'unique': 'кол-во уникальных',
'top': 'мода',
'freq': 'частота моды'},
columns={'producer': 'Производитель платформ'})
| Производитель платформ | |
|---|---|
| кол-во значений | 16591 |
| кол-во уникальных | 10 |
| мода | sony |
| частота моды | 6665 |
Диаграмма размаха.
data['producer'].value_counts().plot.box(
title='Диаграмма размаха\nчастоты встречаемости\nпроизводителя платформ',
label='Производитель платформы',
ylabel='Количество игр\nдля платформ одного производителя',
figsize=(3, 5))
plt.show()
Диаграмма распределения частот.
data['producer'].value_counts().plot.bar(
rot=0,
title='Диаграмма распределения игр по производителям платформ',
xlabel='Производитель платформ',
ylabel='Частота',
figsize=(10, 3))
plt.show()
Таблица распределения частот.
pd.DataFrame(data['producer'].value_counts()).T.rename(
index={'producer': 'количество игр'})
| sony | nintendo | microsoft | pc | sega | atari | snk | bandai | panasonic | nec | |
|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 6665 | 6214 | 2323 | 974 | 258 | 133 | 12 | 6 | 3 | 3 |
Описательная статистика.
pd.DataFrame(data['genre'].describe()).rename(
index={'count': 'кол-во значений',
'unique': 'кол-во уникальных',
'top': 'мода',
'freq': 'частота моды'},
columns={'genre': 'Жанр игры'})
| Жанр игры | |
|---|---|
| кол-во значений | 16591 |
| кол-во уникальных | 12 |
| мода | action |
| частота моды | 3346 |
Диаграмма размаха.
data['genre'].value_counts().plot.box(
title='Диаграмма размаха\nраспределения частоты\nвстречаемости жанра',
label='Жанр',
ylabel='Количество игр\nкаждого жанра',
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data.loc[data['genre'] != 'misc', 'genre'].value_counts().plot.bar(
rot=0,
title='Диаграмма распределения игр по жанрам',
xlabel='Жанр игры',
ylabel='Частота',
figsize=(10, 3))
plt.show()
Таблица распределения частот.
pd.DataFrame(data['genre'].value_counts()).T.rename(
index={'genre': 'количество игр'})
| action | sports | misc | role-playing | shooter | adventure | racing | platform | simulation | fighting | strategy | puzzle | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 3346 | 2331 | 1738 | 1473 | 1318 | 1297 | 1244 | 883 | 864 | 838 | 681 | 578 |
Круговая диаграмма распределения компьютерных игр по наличию оценок пользователей.
(data['user_score'] >= 0).value_counts().rename(
index={0: 'Оценки нет', 1: 'Оценка есть'}
).plot.pie(
title='Круговая диаграмма\nраспределения компьютерных игр' +
'\nпо наличию оценок пользователей',
label='',
figsize=(10, 3))
plt.show()
Таблица относительных частот.
pd.DataFrame((data['user_score'] >= 0).value_counts() /
data.shape[0] * 100).round(0).astype('int').rename(
index={0: 'Оценки нет', 1: 'Оценка есть'},
columns={'user_score': 'Относительная частота, %'}).T
| Оценки нет | Оценка есть | |
|---|---|---|
| Относительная частота, % | 54 | 46 |
Описательная статистика.
descriptive_statistics(data.loc[data['user_score'] >= 0, 'user_score'],
'Оценка пользователей')
| Оценка пользователей | |
|---|---|
| кол-во значений | 7588 |
| кол-во уникальных | 95 |
| мин. | 0.0 |
| -1.5IQR | 4.8 |
| 25 % | 6.4 |
| мода | [7.8] |
| медиана | 7.5 |
| среднее ариф. | 7.13 |
| 75 % | 8.2 |
| +1.5IQR | 10.2 |
| макс. | 9.7 |
| размах | 9.7 |
| межквартильный размах | 1.8 |
Диаграмма размаха.
data.loc[data['user_score'] >= 0, 'user_score'].plot.box(
title='Диаграмма размаха\nраспределения игр' +
'\nпо значению оценки пользователя',
label='Название игры',
ylabel='Оценка пользователей',
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data.loc[data['user_score'] >= 0, 'user_score'].plot.hist(
bins=[0.3 * (n + 1) for n in range(35)],
xticks=[n + 1 for n in range(10)],
figsize=(10, 3))
plt.title('Диаграмма распределения игр по значению оценки пользователя')
plt.xlabel('Оценка пользователей')
plt.ylabel('Частота')
plt.show()
Таблица распределения частот (топ-10).
pd.DataFrame(
data.loc[data['user_score'] >= 0, 'user_score'].value_counts()
).head(10).sort_index().T.rename(index={'user_score': 'Количество игр'})
| 7.3 | 7.5 | 7.7 | 7.8 | 7.9 | 8.0 | 8.1 | 8.2 | 8.3 | 8.5 | |
|---|---|---|---|---|---|---|---|---|---|---|
| Количество игр | 236 | 251 | 240 | 324 | 249 | 290 | 244 | 282 | 254 | 253 |
Круговая диаграмма распределения компьютерных игр по наличию оценок критиков.
(data['critic_score'] > 0).value_counts().rename(
index={0: 'Оценки нет', 1: 'Оценка есть'}
).plot.pie(
title='Круговая диаграмма\nраспределения компьютерных игр' +
'\nпо наличию оценок критиков',
label='',
figsize=(10, 3))
plt.show()
Таблица относительных частот.
pd.DataFrame((data['critic_score'] > 0).value_counts() /
data.shape[0] * 100).round(0).astype('int').rename(
index={0: 'Оценки нет', 1: 'Оценка есть'},
columns={'critic_score': 'Относительная частота, %'}).T
| Оценки нет | Оценка есть | |
|---|---|---|
| Относительная частота, % | 51 | 49 |
Описательная статистика.
descriptive_statistics(data.loc[data['critic_score'] > 0, 'critic_score'],
'Оценка критиков')
| Оценка критиков | |
|---|---|
| кол-во значений | 8135 |
| кол-во уникальных | 82 |
| мин. | 13.0 |
| -1.5IQR | 42.5 |
| 25 % | 60.0 |
| мода | [70.0] |
| медиана | 71.0 |
| среднее ариф. | 68.97 |
| 75 % | 79.0 |
| +1.5IQR | 99.5 |
| макс. | 98.0 |
| размах | 85.0 |
| межквартильный размах | 19.0 |
Диаграмма размаха.
data.loc[data['critic_score'] > 0, 'critic_score'].plot.box(
title='Диаграмма размаха\nраспределения игр\nпо значению оценки критиков',
label='Название игры',
ylabel='Оценка критиков',
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data.loc[data['critic_score'] > 0, 'critic_score'].plot.hist(
bins=[n + 1 for n in range(100)],
xticks=[10 * n for n in range(11)],
figsize=(10, 3))
plt.title('Диаграмма распределения игр по значению оценки критиков')
plt.xlabel('Оценка критиков')
plt.ylabel('Частота')
plt.show()
Таблица распределения частот.
pd.DataFrame(
data.loc[data['critic_score'] > 0, 'critic_score'].value_counts()
).head(10).sort_index().T.rename(index={'critic_score': 'Количество игр'})
| 70.0 | 71.0 | 72.0 | 73.0 | 74.0 | 75.0 | 76.0 | 77.0 | 78.0 | 80.0 | |
|---|---|---|---|---|---|---|---|---|---|---|
| Количество игр | 256 | 254 | 226 | 238 | 226 | 245 | 235 | 225 | 240 | 237 |
Круговая диаграмма распределения компьютерных игр по наличию рейтинга ESRB.
(data['age'] >= 0).value_counts().rename(
index={0: 'Рейтинга нет', 1: 'Рейтинг есть'}
).plot.pie(
title='Круговая диаграмма\nраспределения компьютерных игр' +
'\nпо наличию рейтинга ESRB',
label='',
figsize=(10, 3))
plt.show()
Таблица относительных частот.
pd.DataFrame((data['age'] >= 0).value_counts() /
data.shape[0] * 100).round(0).astype('int').rename(
index={0: 'Оценки нет', 1: 'Оценка есть'},
columns={'age': 'Относительная частота, %'}).T
| Оценка есть | Оценки нет | |
|---|---|---|
| Относительная частота, % | 60 | 40 |
Описательная статистика.
pd.DataFrame(data.loc[data['rating'] != 'nd', 'rating'].describe()).rename(
index={'count': 'кол-во значений',
'unique': 'кол-во уникальных',
'top': 'мода',
'freq': 'частота моды'},
columns={'rating': 'Рейтинг ESRB'})
| Рейтинг ESRB | |
|---|---|
| кол-во значений | 9947 |
| кол-во уникальных | 7 |
| мода | e |
| частота моды | 3992 |
Диаграмма размаха.
data.loc[data['age'] >= 0, 'age'].value_counts().plot.box(
title='Диаграмма размаха\nчастоты встречаемости\nрейтинговой оценки ESRB',
label='Название игры',
ylabel='Количество игр\nв каждой категории',
figsize=(3, 4))
plt.show()
Диаграмма распределения частот.
data.loc[data['age'] >= 0, 'age'].value_counts().sort_index().plot.bar(
rot=0,
title='Диаграмма распределения игр по значению минимального возраста',
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Частота',
figsize=(10, 3))
plt.show()
Таблица распределения частот.
pd.DataFrame(
data.loc[data['age'] >= 0, 'age'].value_counts().sort_index()
).T.rename(index={'age': 'количество игр'})
| 0 | 3 | 10 | 13 | 17 | 18 | 100 | |
|---|---|---|---|---|---|---|---|
| количество игр | 3992 | 8 | 1419 | 2961 | 1563 | 1 | 3 |
Распределение пропусков в значениях оценок критиков и пользователей и в значениях рейтинга ESRB
sns.heatmap(
data.replace([-1, 'nd'], np.nan).sort_values(
by=['rating', 'producer', 'platform'], ascending=False).isna(),
cmap=sns.color_palette(['#000000', '#ffffff'])
)
plt.title('Тепловая карта распределения пропущенных значений')
plt.xlabel('Название признака')
plt.ylabel('Номер записи')
plt.show()
Описательная статистика.
descriptive_statistics(data['total_sales'], 'Продажи в мире, млн копий')
| Продажи в мире, млн копий | |
|---|---|
| кол-во значений | 16591 |
| кол-во уникальных | 1007 |
| мин. | 0.01 |
| -1.5IQR | -0.445 |
| 25 % | 0.06 |
| мода | [0.02] |
| медиана | 0.17 |
| среднее ариф. | 0.54 |
| 75 % | 0.47 |
| +1.5IQR | 0.785 |
| макс. | 82.54 |
| размах | 82.53 |
| межквартильный размах | 0.41 |
Диаграмма размаха.
data['total_sales'].plot.box(
title='Диаграмма размаха\nраспределения игр\nпо общим (мировым) продажам',
label='Название игры',
ylabel='Продажи, млн копий',
ylim=(0, 1.25),
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data.loc[data['total_sales'] < 1, 'total_sales'].plot.hist(figsize=(10, 3))
plt.title('Диаграмма распределения игр по общим (мировым) продажам')
plt.xlabel('Продажи, млн копий')
plt.ylabel('Частота')
plt.show()
Таблица распределения частот.
pd.DataFrame(
data.loc[data['total_sales'] > 0, 'total_sales'].value_counts().head(10).sort_index()
).T.rename(index={'total_sales': 'количество игр'})
| 0.01 | 0.02 | 0.03 | 0.04 | 0.05 | 0.06 | 0.08 | 0.09 | 0.11 | 0.13 | |
|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 782 | 1018 | 799 | 647 | 633 | 313 | 484 | 327 | 382 | 365 |
Круговая диаграмма распределения компьютерных игр по продажам в Северной Америке.
(data['na_sales'] > 0).value_counts().rename(
index={0: 'Продаж не было', 1: 'Продажи были'}
).plot.pie(
title='Круговая диаграмма\nраспределения игр\nпо продажам в Северной Америке',
label='',
figsize=(10, 3))
plt.show()
Таблица относительных частот.
pd.DataFrame((data['na_sales'] > 0).value_counts() /
data.shape[0] * 100).round(0).astype('int').rename(
index={0: 'Продаж не было', 1: 'Продажи были'},
columns={'na_sales': 'Относительная частота, %'}).T
| Продажи были | Продаж не было | |
|---|---|---|
| Относительная частота, % | 73 | 27 |
Описательная статистика.
descriptive_statistics(data.loc[data['na_sales'] > 0, 'na_sales'],
'Продажи в Северной Америке, млн копий')
| Продажи в Северной Америке, млн копий | |
|---|---|
| кол-во значений | 12185 |
| кол-во уникальных | 405 |
| мин. | 0.01 |
| -1.5IQR | -0.28 |
| 25 % | 0.06 |
| мода | [0.02] |
| медиана | 0.14 |
| среднее ариф. | 0.36 |
| 75 % | 0.34 |
| +1.5IQR | 0.56 |
| макс. | 41.36 |
| размах | 41.35 |
| межквартильный размах | 0.28 |
Диаграмма размаха.
data.loc[data['na_sales'] > 0, 'na_sales'].plot.box(
title='Диаграмма размаха\nраспределения игр\nпо продажам в Северной Америке',
label='Название игры',
ylabel='Продажи, млн копий',
ylim=(0, 1),
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data.loc[(data['na_sales'] > 0) & (data['na_sales'] < 1), 'na_sales'].plot.hist(figsize=(10, 3))
plt.title('Диаграмма распределения игр по продажам в Северной Америке')
plt.xlabel('Продажи, млн копий')
plt.ylabel('Количество игр')
plt.show()
Таблица распределения частот.
pd.DataFrame(
data.loc[data['na_sales'] > 0, 'na_sales'].value_counts().head(10).sort_index()
).T.rename(index={'na_sales': 'количество игр'})
| 0.01 | 0.02 | 0.03 | 0.04 | 0.05 | 0.06 | 0.07 | 0.08 | 0.09 | 0.10 | |
|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 544 | 574 | 559 | 546 | 542 | 502 | 489 | 444 | 432 | 406 |
Круговая диаграмма распределения компьютерных игр по продажам в Европе.
(data['eu_sales'] > 0).value_counts().rename(
index={0: 'Продаж не было', 1: 'Продажи были'}
).plot.pie(
title='Круговая диаграмма\nраспределения игр\nпо продажам в Европе',
label='',
figsize=(10, 3))
plt.show()
Таблица относительных частот.
pd.DataFrame((data['eu_sales'] > 0).value_counts() /
data.shape[0] * 100).round(0).astype('int').rename(
index={0: 'Продаж не было', 1: 'Продажи были'},
columns={'eu_sales': 'Относительная частота, %'}).T
| Продажи были | Продаж не было | |
|---|---|---|
| Относительная частота, % | 65 | 35 |
Описательная статистика.
descriptive_statistics(data.loc[data['eu_sales'] > 0, 'eu_sales'],
'Продажи в Европе, млн копий')
| Продажи в Европе, млн копий | |
|---|---|
| кол-во значений | 10825 |
| кол-во уникальных | 308 |
| мин. | 0.01 |
| -1.5IQR | -0.2 |
| 25 % | 0.02 |
| мода | [0.01] |
| медиана | 0.07 |
| среднее ариф. | 0.22 |
| 75 % | 0.2 |
| +1.5IQR | 0.34 |
| макс. | 28.96 |
| размах | 28.95 |
| межквартильный размах | 0.18 |
Диаграмма размаха.
data.loc[data['eu_sales'] > 0, 'eu_sales'].plot.box(
title='Диаграмма размаха\nраспределения игр\nпо продажам в Европе',
label='Название игры',
ylabel='Продажи, млн копий',
ylim=(0, 1),
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data.loc[(data['eu_sales'] > 0) & (data['eu_sales'] < 1), 'eu_sales'].plot.hist(figsize=(10, 3))
plt.title('Диаграмма распределения игр по продажам в Европе')
plt.xlabel('Продажи, млн копий')
plt.ylabel('Количество игр')
plt.show()
Таблица распределения частот.
pd.DataFrame(
data.loc[data['eu_sales'] > 0, 'eu_sales'].value_counts().head(10).sort_index()
).T.rename(index={'eu_sales': 'количество игр'})
| 0.01 | 0.02 | 0.03 | 0.04 | 0.05 | 0.06 | 0.07 | 0.08 | 0.09 | 0.12 | |
|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 1492 | 1306 | 921 | 708 | 560 | 410 | 355 | 308 | 269 | 233 |
Круговая диаграмма распределения компьютерных игр по продажам в Японии.
(data['jp_sales'] > 0).value_counts().rename(
index={0: 'Продаж не было', 1: 'Продажи были'}
).plot.pie(
title='Круговая диаграмма\nраспределения игр\nпо продажам в Японии',
label='',
figsize=(10, 3))
plt.show()
Таблица относительных частот.
pd.DataFrame((data['jp_sales'] > 0).value_counts() /
data.shape[0] * 100).round(0).astype('int').rename(
index={0: 'Продаж не было', 1: 'Продажи были'},
columns={'jp_sales': 'Относительная частота, %'}).T
| Продаж не было | Продажи были | |
|---|---|---|
| Относительная частота, % | 63 | 37 |
Описательная статистика.
descriptive_statistics(data.loc[data['jp_sales'] > 0, 'jp_sales'],
'Продажи в Японии, млн копий')
| Продажи в Японии, млн копий | |
|---|---|
| кол-во значений | 6184 |
| кол-во уникальных | 243 |
| мин. | 0.01 |
| -1.5IQR | -0.17 |
| 25 % | 0.03 |
| мода | [0.02] |
| медиана | 0.07 |
| среднее ариф. | 0.21 |
| 75 % | 0.19 |
| +1.5IQR | 0.31 |
| макс. | 10.22 |
| размах | 10.21 |
| межквартильный размах | 0.16 |
Диаграмма размаха.
data.loc[data['jp_sales'] > 0, 'jp_sales'].plot.box(
title='Диаграмма размаха\nраспределения игр\nпо продажам в Японии',
label='Название игры',
ylabel='Продажи, млн копий',
ylim=(0, 1),
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data.loc[(data['jp_sales'] > 0) & (data['jp_sales'] < 1), 'jp_sales'].plot.hist(figsize=(10, 3))
plt.title('Диаграмма распределения игр по продажам в Японии')
plt.xlabel('Продажи, млн копий')
plt.ylabel('Количество игр')
plt.show()
Таблица распределения частот.
pd.DataFrame(
data.loc[data['jp_sales'] > 0, 'jp_sales'].value_counts().head(10).sort_index()
).T.rename(index={'jp_sales': 'количество игр'})
| 0.01 | 0.02 | 0.03 | 0.04 | 0.05 | 0.06 | 0.07 | 0.08 | 0.09 | 0.10 | |
|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 705 | 739 | 543 | 395 | 321 | 296 | 227 | 220 | 156 | 154 |
Круговая диаграмма распределения компьютерных игр по продажам в остальных регионах.
(data['other_sales'] > 0).value_counts().rename(
index={0: 'Продаж не было', 1: 'Продажи были'}
).plot.pie(
title='Круговая диаграмма\nраспределения игр\nпо продажам в других регионах',
label='',
figsize=(10, 3))
plt.show()
Таблица относительных частот.
pd.DataFrame((data['other_sales'] > 0).value_counts() /
data.shape[0] * 100).round(0).astype('int').rename(
index={0: 'Продаж не было', 1: 'Продажи были'},
columns={'other_sales': 'Относительная частота, %'}).T
| Продажи были | Продаж не было | |
|---|---|---|
| Относительная частота, % | 61 | 39 |
Описательная статистика.
descriptive_statistics(data.loc[data['other_sales'] > 0, 'other_sales'],
'Продажи в остальных регионах, млн копий')
| Продажи в остальных регионах, млн копий | |
|---|---|
| кол-во значений | 10092 |
| кол-во уникальных | 154 |
| мин. | 0.01 |
| -1.5IQR | -0.07 |
| 25 % | 0.01 |
| мода | [0.01] |
| медиана | 0.02 |
| среднее ариф. | 0.08 |
| 75 % | 0.07 |
| +1.5IQR | 0.11 |
| макс. | 10.57 |
| размах | 10.56 |
| межквартильный размах | 0.06 |
Диаграмма размаха.
data.loc[data['other_sales'] > 0, 'other_sales'].plot.box(
title='Диаграмма размаха\nраспределения игр\nпо продажам в других регионах',
label='Название игры',
ylabel='Продажи, млн копий',
ylim=(0, 1),
figsize=(3, 3))
plt.show()
Диаграмма распределения частот.
data.loc[(data['other_sales'] > 0) & (data['other_sales'] < 1), 'other_sales'].plot.hist(figsize=(10, 3))
plt.title('Диаграмма распределения игр по продажам в других регионах')
plt.xlabel('Продажи, млн копий')
plt.ylabel('КОличество игр')
plt.show()
Таблица распределения частот.
pd.DataFrame(
data.loc[data['other_sales'] > 0, 'other_sales'].value_counts().head(10).sort_index()
).T.rename(index={'other_sales': 'количество игр'})
| 0.01 | 0.02 | 0.03 | 0.04 | 0.05 | 0.06 | 0.07 | 0.08 | 0.09 | 0.10 | |
|---|---|---|---|---|---|---|---|---|---|---|
| количество игр | 3457 | 1606 | 927 | 652 | 475 | 393 | 338 | 237 | 185 | 174 |
Диаграмма распределения поколений игровых систем по годам выпуска компьютерных игр.
data.plot.scatter(
x='year_of_release',
y='generation',
xlabel='Год выпуска игры',
ylabel='Поколение игровой системы',
title='Диаграмма рассеяния\n"Поколение игровой системы $-$ год выпуска игры"',
figsize=(6, 3)
)
plt.show()
Диаграмма распределения производителей игровых платформ по годам выпуска компьютерных игр.
data.sort_values(by='producer', ascending=False).plot.scatter(
x='year_of_release',
y='producer',
figsize=(6, 3),
xlabel='Год выпуска игры',
ylabel='Производитель платформы',
title='Диаграмма рассеяния\n"Производитель платформы $-$ год выпуска игры"'
)
plt.show()
Диаграмма распределения игровых платформ по годам выпуска компьютерных игр.
data.plot.scatter(
x='year_of_release',
y='platform',
xlabel='Год выпуска игры',
ylabel='Игровая платформа',
title='Диаграмма рассеяния\n"Игровая платформа $-$ год выпуска игры"',
figsize=(6, 6)
)
plt.show()
Топ-10 платформ с наибольшими суммарными продажами и время их актуальности на рынке компьютерных игр.
lifetime = data.groupby(['producer', 'platform'])['year_of_release'].agg(['min', 'max']).join(
data.groupby(['producer', 'platform'])['total_sales'].agg(['count', 'sum']))
lifetime['range'] = lifetime['max'] - lifetime['min'] + 1
lifetime = lifetime.reset_index().rename(columns={
'producer': 'Производитель платформы',
'platform': 'Платформа',
'min': 'Год выпуска первой игры',
'max': 'Год выпуска последней игры',
'count': 'Количество игр',
'sum': 'Объём продаж в мире, млн копий',
'range': 'Время актуальности платформы, лет'})
lifetime.sort_values(by='Объём продаж в мире, млн копий',
ascending=False).head(10).reset_index(drop=True)
| Производитель платформы | Платформа | Год выпуска первой игры | Год выпуска последней игры | Количество игр | Объём продаж в мире, млн копий | Время актуальности платформы, лет | |
|---|---|---|---|---|---|---|---|
| 0 | sony | ps2 | 2000 | 2011 | 2128 | 1249.95 | 12 |
| 1 | microsoft | x360 | 2005 | 2016 | 1256 | 971.41 | 12 |
| 2 | sony | ps3 | 2006 | 2016 | 1327 | 939.65 | 11 |
| 3 | nintendo | wii | 2006 | 2016 | 1312 | 907.51 | 11 |
| 4 | nintendo | ds | 2004 | 2013 | 2115 | 805.82 | 10 |
| 5 | sony | ps | 1994 | 2003 | 1196 | 730.86 | 10 |
| 6 | nintendo | gba | 2000 | 2007 | 817 | 316.17 | 8 |
| 7 | sony | ps4 | 2013 | 2016 | 392 | 314.14 | 4 |
| 8 | sony | psp | 2004 | 2015 | 1192 | 294.05 | 12 |
| 9 | pc | pc | 1985 | 2016 | 974 | 259.52 | 32 |
Для построения прогноза необходимо исследовать данные за актуальный период.
Из всех производителей игровых платформ только четыре продолжают оставаться на рынке. Кроме того, нужно учитывать, что жизненный цикл одной платформы на рынке составляет 10–12 лет, после окончания которого платформа обычно уходит с рынка.
Проследим, как менялся объём продаж игр для платформ тех производителей, которые ещё остаются на рынке. Выберем среди их платформ потенциально прибыльные.
Динамика количества выпускаемых игр для платформ производства Sony.
plt.figure(figsize=(12, 4))
for platform_name in data.loc[data['producer'] == 'sony', 'platform'] \
.sort_values().unique():
plt.plot(data[data['platform'] == platform_name] \
.groupby('year_of_release')['year_of_release'].agg('count'))
plt.legend(data.loc[data['producer'] == 'sony', 'platform'].sort_values().unique())
plt.title('Графики зависимости' +
'\nколичества выпущенных игр для платформ Sony' +
'\nот года выпуска')
plt.xlabel('Год выпуска')
plt.ylabel('Количество игр')
plt.show()
Динамика объемов продаж игр для платформ производства Sony.
plt.figure(figsize=(12, 4))
for platform_name in data.loc[data['producer'] == 'sony', 'platform'] \
.sort_values().unique():
plt.plot(data[data['platform'] == platform_name] \
.groupby('year_of_release')['total_sales'].agg('sum'))
plt.legend(data.loc[data['producer'] == 'sony', 'platform'].sort_values().unique())
plt.title('Графики зависимости' +
'\nмировых продаж игр для платформ Sony' +
'\nот года выпуска')
plt.xlabel('Год выпуска')
plt.ylabel('Продажи, млн копий')
plt.show()
Динамика количества выпускаемых игр для платформ производства Nintendo.
plt.figure(figsize=(12, 4))
for platform_name in data.loc[data['producer'] == 'nintendo', 'platform'] \
.sort_values().unique():
plt.plot(data[data['platform'] == platform_name] \
.groupby('year_of_release')['year_of_release'].agg('count'))
plt.legend(data.loc[data['producer'] == 'nintendo', 'platform'].sort_values().unique())
plt.title('Графики зависимости' +
'\nколичества выпущенных игр для платформ Nintendo' +
'\nот года выпуска')
plt.xlabel('Год выпуска')
plt.ylabel('Количество игр')
plt.show()
Динамика объемов продаж игр для платформ производства Nintendo.
plt.figure(figsize=(12, 4))
for platform_name in data.loc[data['producer'] == 'nintendo', 'platform'] \
.sort_values().unique():
plt.plot(data[data['platform'] == platform_name] \
.groupby('year_of_release')['total_sales'].agg('sum'))
plt.legend(data.loc[data['producer'] == 'nintendo', 'platform'].sort_values().unique())
plt.title('Графики зависимости' +
'\nмировых продаж игр для платформ Nintendo' +
'\nот года выпуска')
plt.xlabel('Год выпуска')
plt.ylabel('Продажи, млн копий')
plt.show()
Динамика количества выпускаемых игр для платформ производства Microsoft.
plt.figure(figsize=(12, 4))
for platform_name in data.loc[data['producer'] == 'microsoft', 'platform'] \
.sort_values().unique():
plt.plot(data[data['platform'] == platform_name] \
.groupby('year_of_release')['year_of_release'].agg('count'))
plt.legend(data.loc[data['producer'] == 'microsoft', 'platform'].sort_values().unique())
plt.title('Графики зависимости' +
'\nколичества выпущенных игр для платформ Microsoft' +
'\nот года выпуска')
plt.xlabel('Год выпуска')
plt.ylabel('Количество игр')
plt.show()
Динамика объемов продаж игр для платформ производства Microsoft.
plt.figure(figsize=(12, 4))
for platform_name in data.loc[data['producer'] == 'microsoft', 'platform'] \
.sort_values().unique():
plt.plot(data[data['platform'] == platform_name] \
.groupby('year_of_release')['total_sales'].agg('sum'))
plt.legend(data.loc[data['producer'] == 'microsoft', 'platform'].sort_values().unique())
plt.title('Графики зависимости' +
'\nмировых продаж игр для платформ Microsoft' +
'\nот года выпуска')
plt.xlabel('Год выпуска')
plt.ylabel('Продажи, млн копий')
plt.show()
Динамика количества выпускаемых игр для персонального компьютера.
plt.figure(figsize=(12, 4))
plt.plot(data[data['platform'] == 'pc'] \
.groupby('year_of_release')['year_of_release'].agg('count'))
plt.title('Графики зависимости' +
'\nколичества выпущенных игр для персонального компьютера' +
'\nот года выпуска')
plt.xlabel('Год выпуска')
plt.ylabel('Количество игр')
plt.show()
Динамика объемов продаж игр для персонального компьютера.
plt.figure(figsize=(12, 4))
plt.plot(data[data['platform'] == 'pc'] \
.groupby('year_of_release')['total_sales'].agg('sum'))
plt.title('Графики зависимости' +
'\nмировых продаж игр для персонального компьютера' +
'\nот года выпуска')
plt.xlabel('Год выпуска')
plt.ylabel('Продажи, млн копий')
plt.show()
Наибольший интерес представляют 6 платформ: 5 игровых приставок, а также персональный компьютер. Все они являются игровыми системами последнего, восьмого поколения. Это приставки
Все эти платформы начали появляться после 2011 года. Выделим записи об играх для этого временного периода из общего набора данных и последующий анализ будем проводить для них.
actual_data = data[data['year_of_release'] >= 2012]
actual_data.sample(5)
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | total_sales | age | generation | producer | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 14523 | tiger woods pga tour 14 | ps3 | 2013 | sports | 0.16 | 0.14 | 0.00 | 0.07 | 74.0 | 3.8 | e | 0.37 | 0 | 7 | sony |
| 15834 | shovel knight | 3ds | 2015 | platform | 0.08 | 0.04 | 0.02 | 0.01 | 90.0 | 8.2 | e | 0.15 | 0 | 8 | nintendo |
| 16194 | trackmania turbo | ps4 | 2016 | action | 0.03 | 0.26 | 0.00 | 0.05 | 81.0 | 7.9 | e | 0.34 | 0 | 8 | sony |
| 15764 | metal gear solid v: the phantom pain | ps3 | 2015 | action | 0.22 | 0.13 | 0.22 | 0.07 | -1.0 | 7.2 | m | 0.64 | 17 | 7 | sony |
| 14842 | shirahana no ori: hiiro no kakera 4 - shiki no... | psp | 2013 | adventure | 0.00 | 0.00 | 0.01 | 0.00 | -1.0 | -1.0 | nd | 0.01 | -1 | 7 | sony |
Диаграммы размаха значений годовых объёмов продаж по миру для каждой платформы.
pivot = actual_data.pivot_table(index='year_of_release',
columns='platform',
values='total_sales',
aggfunc='sum')
pivot.reset_index(drop=True, inplace=True)
pivot.plot.box()
plt.title('Диаграмма размаха\nраспределения годовых продаж игр по платформам')
plt.xlabel('Платформа')
plt.ylabel('Годовой объём продаж, млн копий')
plt.show()
Диаграммы размаха значений объёма мировых продаж игр для каждой платформы.
pivot = actual_data.pivot_table(index='name',
columns='platform',
values='total_sales')
pivot.reset_index(drop=True, inplace=True)
pivot.plot.box()
plt.title('Диаграмма размаха' +
'\nраспределения игр по объёму мировых продаж' +
'\nдля каждой платформы')
plt.xlabel('Платформа')
plt.ylabel('Объём продаж одной игры, млн копий')
plt.show()
pivot = actual_data.pivot_table(index='name',
columns='platform',
values='total_sales')
pivot.reset_index(drop=True, inplace=True)
pivot.plot.box()
plt.ylim(0, 2)
plt.title('Диаграмма размаха' +
'\nраспределения игр по объёму мировых продаж' +
'\nдля каждой платформы')
plt.xlabel('Платформа')
plt.ylabel('Объём продаж одной игры, млн копий')
plt.yticks([0.2*n for n in range(10)])
plt.show()
Оценка пользователей
Диаграмма рассеяния "Объём мировых продаж — оценка пользователей".
actual_data[(actual_data['platform'] == 'ps4') &
(actual_data['user_score'] > 0)].plot.scatter(
x='user_score',
y='total_sales',
xlabel='Оценка пользователей',
ylabel='Объём мировых продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка пользователей"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'ps4') &
(actual_data['user_score'] > 0), 'user_score'].corr(
actual_data.loc[(actual_data['platform'] == 'ps4') &
(actual_data['user_score'] > 0), 'total_sales']).round(2)
-0.03
Оценка критиков
Диаграмма рассеяния "Объём мировых продаж — оценка критиков".
actual_data[(actual_data['platform'] == 'ps4') &
(actual_data['critic_score'] > 0)].plot.scatter(
x='critic_score',
y='total_sales',
xlabel='Оценка критиков',
ylabel='Объём мировых продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка критиков"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'ps4') &
(actual_data['critic_score'] > 0), 'critic_score'].corr(
actual_data.loc[(actual_data['platform'] == 'ps4') &
(actual_data['critic_score'] > 0), 'total_sales']).round(2)
0.41
График зависимости медианного значения объёма мировых продаж от оценки критиков.
actual_data[(actual_data['platform'] == 'ps4') &
(actual_data['critic_score'] > 0)] \
.groupby('critic_score')['total_sales'].agg('median').plot(figsize=(6, 4))
plt.xlabel('Оценка критиков')
plt.ylabel('Объём продаж, млн копий')
plt.title('График зависимости' +
'\nмедианного значения объёма мировых продаж' +
'\nот оценки критиков')
plt.show()
Оценка пользователей
Диаграмма рассеяния "Объём мировых продаж — оценка пользователей".
actual_data[(actual_data['platform'] == 'psv') &
(actual_data['user_score'] > 0)].plot.scatter(
x='user_score',
y='total_sales',
xlabel='Оценка пользователей',
ylabel='Объём мировых продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка пользователей"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'psv') &
(actual_data['user_score'] > 0), 'user_score'].corr(
actual_data.loc[(actual_data['platform'] == 'psv') &
(actual_data['user_score'] > 0), 'total_sales']).round(2)
-0.0
Оценка критиков
Диаграмма рассеяния "Объём мировых продаж — оценка критиков".
actual_data[(actual_data['platform'] == 'psv') &
(actual_data['critic_score'] > 0)].plot.scatter(
x='critic_score',
y='total_sales',
xlabel='Оценка критиков',
ylabel='Объём мировых продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка критиков"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'psv') &
(actual_data['critic_score'] > 0), 'critic_score'].corr(
actual_data.loc[(actual_data['platform'] == 'psv') &
(actual_data['critic_score'] > 0), 'total_sales']).round(2)
0.09
Кто оказался "белой вороной"?
actual_data[(actual_data['platform'] == 'psv') &
(actual_data['critic_score'] > 0) &
(actual_data['critic_score'] < 40)]
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | total_sales | age | generation | producer | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 13728 | call of duty black ops: declassified | psv | 2012 | action | 0.71 | 0.43 | 0.07 | 0.26 | 33.0 | 4.8 | m | 1.47 | 17 | 8 | sony |
Коэффициент корреляции (без учёта выброса).
actual_data.loc[(actual_data['platform'] == 'psv') &
(actual_data['critic_score'] > 0) &
(actual_data['critic_score'] > 40), 'critic_score'].corr(
actual_data.loc[(actual_data['platform'] == 'psv') &
(actual_data['critic_score'] > 0) &
(actual_data['critic_score'] > 40), 'total_sales']).round(2)
0.3
График зависимости медианного значения объёма мировых продаж от оценки критиков (без учёта выброса).
actual_data[(actual_data['platform'] == 'psv') &
(actual_data['critic_score'] > 0) &
(actual_data['critic_score'] > 40)] \
.groupby('critic_score')['total_sales'].agg('median').plot(figsize=(6, 4))
plt.xlabel('Оценка критиков')
plt.ylabel('Объём продаж, млн копий')
plt.title('График зависимости' +
'\nмедианного значения объёма мировых продаж' +
'\nот оценки критиков')
plt.show()
Оценка пользователей
Диаграмма рассеяния "Объём мировых продаж — оценка пользователей".
actual_data[(actual_data['platform'] == 'wiiu') &
(actual_data['user_score'] > 0)].plot.scatter(
x='user_score',
y='total_sales',
xlabel='Оценка пользователей',
ylabel='Объём мировых продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка пользователей"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'wiiu') &
(actual_data['user_score'] > 0), 'user_score'].corr(
actual_data.loc[(actual_data['platform'] == 'wiiu') &
(actual_data['user_score'] > 0), 'total_sales']).round(2)
0.4
График зависимости медианного значения объёма мировых продаж от оценки пользователей.
actual_data[(actual_data['platform'] == 'wiiu') &
(actual_data['user_score'] > 0)] \
.groupby('user_score')['total_sales'].agg('median').plot(figsize=(6, 4))
plt.xlabel('Оценка пользователей')
plt.ylabel('Объём продаж, млн копий')
plt.title('График зависимости' +
'\nмедианного значения объёма мировых продаж' +
'\nот оценки пользователей')
plt.show()
Оценка критиков
Диаграмма рассеяния "Объём мировых продаж — оценка критиков".
actual_data[(actual_data['platform'] == 'wiiu') &
(actual_data['critic_score'] > 0)].plot.scatter(
x='critic_score',
y='total_sales',
xlabel='Оценка критиков',
ylabel='Объём мировых продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка критиков"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'wiiu') &
(actual_data['critic_score'] > 0), 'critic_score'].corr(
actual_data.loc[(actual_data['platform'] == 'wiiu') &
(actual_data['critic_score'] > 0), 'total_sales']).round(2)
0.35
График зависимости медианного значения объёма мировых продаж от оценки критиков.
actual_data[(actual_data['platform'] == 'wiiu') &
(actual_data['critic_score'] > 0)] \
.groupby('critic_score')['total_sales'].agg('median').plot(figsize=(6, 4))
plt.xlabel('Оценка критиков')
plt.ylabel('Объём продаж, млн копий')
plt.title('График зависимости' +
'\nмедианного значения объёма мировых продаж' +
'\nот оценки критиков')
plt.show()
Оценка пользователей
Диаграмма рассеяния "Объём мировых продаж — оценка пользователей".
actual_data[(actual_data['platform'] == '3ds') &
(actual_data['user_score'] > 0)].plot.scatter(
x='user_score',
y='total_sales',
xlabel='Оценка пользователей',
ylabel='Объём продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка пользователей"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == '3ds') &
(actual_data['user_score'] > 0), 'user_score'].corr(
actual_data.loc[(actual_data['platform'] == '3ds') &
(actual_data['user_score'] > 0), 'total_sales']).round(2)
0.2
Оценка критиков
Диаграмма рассеяния "Объём мировых продаж — оценка критиков".
actual_data[(actual_data['platform'] == '3ds') &
(actual_data['critic_score'] > 0)].plot.scatter(
x='critic_score',
y='total_sales',
xlabel='Оценка критиков',
ylabel='Объём продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка критиков"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == '3ds') &
(actual_data['critic_score'] > 0), 'critic_score'].corr(
actual_data.loc[(actual_data['platform'] == '3ds') &
(actual_data['critic_score'] > 0), 'total_sales']).round(2)
0.32
График зависимости медианного значения объёма мировых продаж от оценки критиков.
actual_data[(actual_data['platform'] == '3ds') &
(actual_data['critic_score'] > 0)] \
.groupby('critic_score')['total_sales'].agg('median').plot(figsize=(6, 4))
plt.xlabel('Оценка критиков')
plt.ylabel('Объём продаж, млн копий')
plt.title('График зависимости' +
'\nмедианного значения объёма мировых продаж' +
'\nот оценки критиков')
plt.show()
Оценка пользователей
Диаграмма рассеяния "Объём мировых продаж — оценка пользователей".
actual_data[(actual_data['platform'] == 'xone') &
(actual_data['user_score'] > 0)].plot.scatter(
x='user_score',
y='total_sales',
xlabel='Оценка пользователей',
ylabel='Объём продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка пользователей"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'xone') &
(actual_data['user_score'] > 0), 'user_score'].corr(
actual_data.loc[(actual_data['platform'] == 'xone') &
(actual_data['user_score'] > 0), 'total_sales']).round(2)
-0.07
Оценка критиков
Диаграмма рассеяния "Объём мировых продаж — оценка критиков".
actual_data[(actual_data['platform'] == 'xone') &
(actual_data['critic_score'] > 0)].plot.scatter(
x='critic_score',
y='total_sales',
xlabel='Оценка критиков',
ylabel='Объём продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка критиков"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'xone') &
(actual_data['critic_score'] > 0), 'critic_score'].corr(
actual_data.loc[(actual_data['platform'] == 'xone') &
(actual_data['critic_score'] > 0), 'total_sales']).round(2)
0.42
График зависимости медианного значения объёма мировых продаж от оценки критиков.
actual_data[(actual_data['platform'] == 'xone') &
(actual_data['critic_score'] > 0)] \
.groupby('critic_score')['total_sales'].agg('median').plot(figsize=(6, 4))
plt.xlabel('Оценка критиков')
plt.ylabel('Объём продаж, млн копий')
plt.title('График зависимости' +
'\nмедианного значения объёма мировых продаж' +
'\nот оценки критиков')
plt.show()
Оценка пользователей
Диаграмма рассеяния "Объём мировых продаж — оценка пользователей".
actual_data[(actual_data['platform'] == 'pc') &
(actual_data['user_score'] > 0)].plot.scatter(
x='user_score',
y='total_sales',
xlabel='Оценка пользователей',
ylabel='Объём продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка пользователей"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'pc') &
(actual_data['user_score'] > 0), 'user_score'].corr(
actual_data.loc[(actual_data['platform'] == 'pc') &
(actual_data['user_score'] > 0), 'total_sales']).round(2)
-0.12
Оценка критиков
Диаграмма рассеяния "Объём мировых продаж — оценка критиков".
actual_data[(actual_data['platform'] == 'pc') &
(actual_data['critic_score'] > 0)].plot.scatter(
x='critic_score',
y='total_sales',
xlabel='Оценка критиков',
ylabel='Объём продаж, млн копий',
title='Диаграмма рассеяния\n"Объём мировых продаж $-$ оценка критиков"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['platform'] == 'pc') &
(actual_data['critic_score'] > 0), 'critic_score'].corr(
actual_data.loc[(actual_data['platform'] == 'pc') &
(actual_data['critic_score'] > 0), 'total_sales']).round(2)
0.24
График зависимости медианного значения объёма мировых продаж от оценки критиков.
actual_data[(actual_data['platform'] == 'pc') &
(actual_data['critic_score'] > 0)] \
.groupby('critic_score')['total_sales'].agg('median').plot(figsize=(6, 4))
plt.xlabel('Оценка критиков')
plt.ylabel('Объём продаж, млн копий')
plt.title('График зависимости' +
'\nмедианного значения объёма мировых продаж' +
'\nот оценки критиков')
plt.show()
Диаграмма рассеяния "Оценка пользователей — оценка критиков"
actual_data.loc[(actual_data['critic_score'] > 0) &
(actual_data['user_score'] > 0)].plot.scatter(
x='critic_score',
y='user_score',
xlabel='Оценка критиков',
ylabel='Оценка пользователей',
title='Диаграмма рассеяния\n"Оценка пользователей $-$ оценка критиков"',
alpha=0.2,
figsize=(6, 4))
plt.show()
Коэффициент корреляции.
actual_data.loc[(actual_data['critic_score'] > 0) &
(actual_data['user_score'] > 0), 'critic_score'].corr(
actual_data.loc[(actual_data['critic_score'] > 0) &
(actual_data['user_score'] > 0), 'user_score']).round(2)
0.52
График сравнения медианных значений оценок пользователей и оценок критиков.
actual_data.loc[(actual_data['critic_score'] > 0) &
(actual_data['user_score'] > 0)] \
.groupby('critic_score')['user_score'].agg('median').plot(figsize=(6, 4))
plt.xlabel('Оценка критиков')
plt.ylabel('Оценка пользователей')
plt.title('График зависимости' +
'\nмедианных значений оценок пользователей и' +
'\nоценок критиков')
plt.show()
Распределение пропусков в значениях оценок критиков и пользователей и в значениях рейтинга ESRB
sns.heatmap(
actual_data.replace([-1, 'nd'], np.nan).sort_values(
by=['rating', 'producer', 'platform', 'genre']).isna(),
cmap=sns.color_palette(['#000000', '#ffffff'])
)
plt.title('Тепловая карта\nраспределения пропущенных значений')
plt.xlabel('Название признака')
plt.ylabel('Номер записи')
plt.show()
Диаграмма распределения.
actual_data['genre'].value_counts().sort_index().plot.bar(
rot=0,
title='Диаграмма распределения игр по жанрам',
xlabel='Жанр игры',
ylabel='Количество выпущенных игр',
figsize=(12, 4))
plt.show()
Диаграммы размаха значений объёмов продаж по миру для игр каждого жанра.
actual_data.pivot_table(index='name',
columns='genre',
values='total_sales'
).plot.box(
xlabel='Жанр игры',
ylabel='Объём продаж, млн копий',
title='Диаграмма размаха' +
'распределения игр по объёму мировых продаж для разных платформ',
ylim=(0, 3.5),
figsize=(12, 5)
)
plt.show()
Диаграмма распределения.
actual_data.groupby('genre')['total_sales'].agg('sum').plot.bar(
rot=0,
xlabel='Жанры',
ylabel='Объём продаж, млн копий',
title='Диаграмма распределения мирового объёма продаж игр каждого жанра',
figsize=(12, 4))
plt.show()
Наибольший объём продаж имеют игры жанров экшен, шутеры и ролевые игры. Замыкают топ-5 игр с самым высоким объёмом продаж спортивные игры, а также (на одном уровне) гонки и платформеры.
Хуже всего продаются головоломки, стратегии и квесты.
Наибольшее число копий одной игры продаётся в жанре шутер. В среднем одна игра продаётся в объёме 450 тыс. копий. Причём для половины всех игр этого жанра продажи могли доходить до 1,3 млн копий. А максимальные продажи могли доходить до 3,2 млн копий.
Следующими по величине объёма продаж одной игры идут платформеры и спортивные игры. В среднем одна игра продаётся в объёме 250 тыс. копий (платформеры) и 200 тыс. копий (спортивные игры). Причём для половины всех игр жанра платформеры продажи могли доходить тоже до 1,3 млн копий. А максимальные продажи могли доходить до 2,2 млн копий. Максимальные продажи спортивных игр могли доходить только до 1,5 млн копий.
Распределение продаж игр жанра гонки почти такое же как у спортивных игр, но медианные объёмы продаж всё же ниже.
У лидеров по общим суммарным продажам — экшенов и ролевых игр — медианные значений объёмов продаж одной игры низкие: 100–200 тыс. копий.
Несмотря на низкий средний спрос на одну игру, производители игр больше всего выпускают экшены (1000 наименований). Ролевые игры идут на втором месте: их выпущено почти в 2,5 раза меньше, чем экшенов (400 наименований).
На третьем месте находятся квесты (300 наименований), но объём продаж у них низкий.
Другие игры, лидирующие по объёмам продаж — шутеры и спортивные игры, выпущены по 250–300 наименований.
А вот платформеров выпускается мало, хотя спрос на них высок.
Головоломки и стратегии выпускаются также мало, как и продаются: поэтому они полностью покрывают спрос на них.
Хотя нам не известна стоимость игр, но считая, что она для разных игр находится приблизительно на одинаковом уровне, можно полагать, что играми самых прибыльных жанров окажутся игры с высоким средним объёмом продаж: шутеры, платформеры и спортивные игры.
Распределение долей платформ в объёме продаж.
sales = actual_data.groupby('platform')['na_sales'].agg(['count', 'sum']).join(
(actual_data.groupby('platform')['na_sales'].agg('sum') /
actual_data['na_sales'].sum() * 100).round(1)) \
.reset_index().rename(columns={
'platform': 'Платформа',
'count':
'Количество выпущеных игр',
'sum': 'Объём продаж, млн копий',
'na_sales': 'Доля в объёме продаж, %'
})
sales.sort_values(by='Доля в объёме продаж, %', ascending=False).head(5)
| Платформа | Количество выпущеных игр | Объём продаж, млн копий | Доля в объёме продаж, % | |
|---|---|---|---|---|
| 9 | x360 | 295 | 140.12 | 23.7 |
| 4 | ps4 | 392 | 108.74 | 18.4 |
| 3 | ps3 | 493 | 103.44 | 17.5 |
| 10 | xone | 247 | 93.12 | 15.8 |
| 0 | 3ds | 398 | 55.31 | 9.4 |
Распределение долей жанров в объёме продаж игр (топ-5 самых популярных жанров).
sales = actual_data.groupby('genre')['na_sales'].agg(['count', 'sum']).join(
(actual_data.groupby('genre')['na_sales'].agg('sum') /
actual_data['na_sales'].sum() * 100).round(1)) \
.reset_index().rename(columns={
'genre': 'Жанр',
'count': 'Количество выпущеных игр',
'sum': 'Объём продаж, млн копий',
'na_sales': 'Доля в объёме продаж, %'
})
sales.sort_values(by='Доля в объёме продаж, %', ascending=False).head(5)
| Жанр | Количество выпущеных игр | Объём продаж, млн копий | Доля в объёме продаж, % | |
|---|---|---|---|---|
| 0 | action | 1034 | 177.92 | 30.1 |
| 8 | shooter | 238 | 144.79 | 24.5 |
| 10 | sports | 268 | 81.53 | 13.8 |
| 7 | role-playing | 371 | 64.00 | 10.8 |
| 3 | misc | 192 | 38.19 | 6.5 |
Диаграммы размаха значений объёмов продаж игр с определённым рейтингом ESRB (и определённым минимальным возрастом пользователя).
actual_data[(actual_data['age'] != 100) &
(actual_data['age'] != 3)].pivot_table(
index='name', columns='age', values='na_sales', aggfunc='sum').plot.box(
ylim=(-0.05, 2.5),
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Объём продаж, млн копий',
title='Диаграмма размаха' +
'\nраспределения игр по объёму продаж' +
'\nв Северной Америке' +
'\nдля разных возрастных категорий',
figsize=(6, 4)
)
plt.show()
Диаграмма распределения.
actual_data[(actual_data['age'] != 100) &
(actual_data['age'] != 3)] \
.groupby('age')['na_sales'].agg('sum').plot.bar(
rot=0,
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Объём продаж, млн копий',
title='Диаграмма распределения' +
'\nобъёмов продаж игр' +
'\nв Северной Америке' +
'\nдля разных возрастных категорий',
figsize=(6, 3)
)
plt.show()
Распределение долей платформ в объёме продаж.
sales = actual_data.groupby('platform')['eu_sales'].agg(['count', 'sum']).join(
(actual_data.groupby('platform')['eu_sales'].agg('sum') /
actual_data['eu_sales'].sum() * 100).round(1)) \
.reset_index().rename(columns={
'platform': 'Платформа',
'count':
'Количество выпущеных игр',
'sum': 'Объём продаж, млн копий',
'eu_sales': 'Доля в объёме продаж, %'
})
sales.sort_values(by='Доля в объёме продаж, %', ascending=False).head(5)
| Платформа | Количество выпущеных игр | Объём продаж, млн копий | Доля в объёме продаж, % | |
|---|---|---|---|---|
| 4 | ps4 | 392 | 141.09 | 27.8 |
| 3 | ps3 | 493 | 106.86 | 21.1 |
| 9 | x360 | 295 | 74.55 | 14.7 |
| 10 | xone | 247 | 51.59 | 10.2 |
| 0 | 3ds | 398 | 42.64 | 8.4 |
Распределение долей жанров в объёме продаж игр (топ-5 самых популярных жанров).
sales = actual_data.groupby('genre')['eu_sales'].agg(['count', 'sum']).join(
(actual_data.groupby('genre')['eu_sales'].agg('sum') /
actual_data['eu_sales'].sum() * 100).round(1)) \
.reset_index().rename(columns={
'genre': 'Жанр',
'count': 'Количество выпущеных игр',
'sum': 'Объём продаж, млн копий',
'eu_sales': 'Доля в объёме продаж, %'
})
sales.sort_values(by='Доля в объёме продаж, %', ascending=False).head(5)
| Жанр | Количество выпущеных игр | Объём продаж, млн копий | Доля в объёме продаж, % | |
|---|---|---|---|---|
| 0 | action | 1034 | 159.82 | 31.5 |
| 8 | shooter | 238 | 113.50 | 22.4 |
| 10 | sports | 268 | 69.09 | 13.6 |
| 7 | role-playing | 371 | 48.53 | 9.6 |
| 6 | racing | 115 | 27.29 | 5.4 |
Диаграммы размаха значений объёмов продаж игр с определённым рейтингом ESRB (и определённым минимальным возрастом пользователя).
actual_data[(actual_data['age'] != 100) & (actual_data['age'] != 3)].pivot_table(
index='name', columns='age', values='eu_sales', aggfunc='sum').plot.box(
ylim=(-0.05, 2),
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Объём продаж, млн копий',
title='Диаграмма размаха' +
'\nраспределения игр по объёму продаж' +
'\nв Европе' +
'\nдля разных возрастных категорий',
figsize=(6, 4)
)
plt.show()
Диаграмма распределения.
actual_data[(actual_data['age'] != 100) &
(actual_data['age'] != 3)] \
.groupby('age')['eu_sales'].agg('sum').plot.bar(
rot=0,
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Объём продаж, млн копий',
title='Диаграмма размаха' +
'\nраспределения объёмов продаж игр' +
'\nв Европе' +
'\nдля разных возрастных категорий',
figsize=(6, 3)
)
plt.show()
Распределение долей платформ в объёме продаж.
sales = actual_data.groupby('platform')['jp_sales'].agg(['count', 'sum']).join(
(actual_data.groupby('platform')['jp_sales'].agg('sum') /
actual_data['jp_sales'].sum() * 100).round(1)) \
.reset_index().rename(columns={
'platform': 'Платформа',
'count':
'Количество выпущеных игр',
'sum': 'Объём продаж, млн копий',
'jp_sales': 'Доля в объёме продаж, %'
})
sales.sort_values(by='Доля в объёме продаж, %', ascending=False).head(5)
| Платформа | Количество выпущеных игр | Объём продаж, млн копий | Доля в объёме продаж, % | |
|---|---|---|---|---|
| 0 | 3ds | 398 | 87.84 | 45.6 |
| 3 | ps3 | 493 | 35.29 | 18.3 |
| 6 | psv | 411 | 21.04 | 10.9 |
| 4 | ps4 | 392 | 15.96 | 8.3 |
| 8 | wiiu | 147 | 13.01 | 6.7 |
Распределение долей жанров в объёме продаж игр (топ-5 самых популярных жанров).
sales = actual_data.groupby('genre')['jp_sales'].agg(['count', 'sum']).join(
(actual_data.groupby('genre')['jp_sales'].agg('sum') /
actual_data['jp_sales'].sum() * 100).round(1)) \
.reset_index().rename(columns={
'genre': 'Жанр',
'count': 'Количество выпущеных игр',
'sum': 'Объём продаж, млн копий',
'jp_sales': 'Доля в объёме продаж, %'
})
sales.sort_values(by='Доля в объёме продаж, %', ascending=False).head(5)
| Жанр | Количество выпущеных игр | Объём продаж, млн копий | Доля в объёме продаж, % | |
|---|---|---|---|---|
| 7 | role-playing | 371 | 65.47 | 34.0 |
| 0 | action | 1034 | 52.80 | 27.4 |
| 3 | misc | 192 | 12.86 | 6.7 |
| 9 | simulation | 83 | 10.41 | 5.4 |
| 2 | fighting | 109 | 9.44 | 4.9 |
Диаграммы размаха значений объёмов продаж игр с определённым рейтингом ESRB (и определённым минимальным возрастом пользователя).
actual_data[(actual_data['age'] != 100) & (actual_data['age'] != 3)].pivot_table(
index='name', columns='age', values='jp_sales', aggfunc='sum').plot.box(
ylim=(-0.01, 0.4),
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Объём продаж, млн копий',
title='Диаграмма размаха' +
'\nраспределения игр по объёму продаж' +
'\nв Японии' +
'\nдля разных возрастных категорий',
figsize=(6, 4)
)
plt.show()
Диаграмма распределения.
actual_data[(actual_data['age'] != 100) &
(actual_data['age'] != 3)] \
.groupby('age')['jp_sales'].agg('sum').plot.bar(
rot=0,
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Объём продаж, млн копий',
title='Диаграмма размаха' +
'\nраспределения объёмов продаж игр' +
'\nв Японии' +
'\nдля разных возрастных категорий',
figsize=(6, 3)
)
plt.show()
Распределение долей платформ в объёме продаж.
sales = actual_data.groupby('platform')['other_sales'].agg(['count', 'sum']).join(
(actual_data.groupby('platform')['other_sales'].agg('sum') /
actual_data['other_sales'].sum() * 100).round(1)) \
.reset_index().rename(columns={
'platform': 'Платформа',
'count':
'Количество выпущеных игр',
'sum': 'Объём продаж, млн копий',
'other_sales': 'Доля в объёме продаж, %'
})
sales.sort_values(by='Доля в объёме продаж, %', ascending=False).head(5)
| Платформа | Количество выпущеных игр | Объём продаж, млн копий | Доля в объёме продаж, % | |
|---|---|---|---|---|
| 4 | ps4 | 392 | 48.35 | 30.9 |
| 3 | ps3 | 493 | 43.27 | 27.7 |
| 9 | x360 | 295 | 20.41 | 13.1 |
| 10 | xone | 247 | 14.27 | 9.1 |
| 0 | 3ds | 398 | 8.87 | 5.7 |
Распределение долей жанров в объёме продаж игр (топ-5 самых популярных жанров).
sales = actual_data.groupby('genre')['other_sales'].agg(['count', 'sum']).join(
(actual_data.groupby('genre')['other_sales'].agg('sum') /
actual_data['other_sales'].sum() * 100).round(1)) \
.reset_index().rename(columns={
'genre': 'Жанр',
'count': 'Количество выпущеных игр',
'sum': 'Объём продаж, млн копий',
'other_sales': 'Доля в объёме продаж, %'
})
sales.sort_values(by='Доля в объёме продаж, %', ascending=False).head(5)
| Жанр | Количество выпущеных игр | Объём продаж, млн копий | Доля в объёме продаж, % | |
|---|---|---|---|---|
| 0 | action | 1034 | 51.21 | 32.8 |
| 8 | shooter | 238 | 37.26 | 23.8 |
| 10 | sports | 268 | 22.44 | 14.4 |
| 7 | role-playing | 371 | 14.83 | 9.5 |
| 3 | misc | 192 | 7.67 | 4.9 |
Диаграммы размаха значений объёмов продаж игр с определённым рейтингом ESRB (и определённым минимальным возрастом пользователя).
actual_data[(actual_data['age'] != 100) & (actual_data['age'] != 3)].pivot_table(
index='name', columns='age', values='other_sales', aggfunc='sum').plot.box(
ylim=(-0.01, 0.65),
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Объём продаж, млн копий',
title='Диаграмма размаха' +
'\nраспределения игр по объёму продаж' +
'\nв других регионах' +
'\nдля разных возрастных категорий',
figsize=(6, 4)
)
plt.show()
Диаграмма распределения.
actual_data[(actual_data['age'] != 100) &
(actual_data['age'] != 3)] \
.groupby('age')['other_sales'].agg('sum').plot.bar(
rot=0,
xlabel='Минимальный возраст (согласно рейтингу ESRB)',
ylabel='Объём продаж, млн копий',
title='Диаграмма размаха' +
'\nраспределения объёмов продаж игр' +
'\nв других регионах' +
'\nдля разных возрастных категорий',
figsize=(6, 3)
)
plt.show()
Нулевую гипотезу сформулируем так, чтобы использовался знак равенства. Поэтому при проверке гипотезы о равенстве средних двух совокупностей нулевая гипотеза будет звучать так: «да, средние двух выборок равны». Если будем выяснять, есть ли разница между совокупностями, то нулевая гипотеза будет такая: «разницы между средними двух выборок нет, средние равны».
Альтернативную гипотезу сформулируем путём отрицания нулевой гипотезы. Такая альтернативная гипотеза будет двусторонней, потому что есть возможное отклонение и в большую, и в меньшую стороны.
Поскольку значений в выборках много (больше 50), можно использовать t-статистику, так как при таком объёме выборки распределение Стьюдента приближается к нормальному распределению.
Сформулируем нулевую и альтернативную гипотезы.
$H_0:$ средние пользовательские оценки игр для платформы Xbox One и персонального компьютера равны.
$H_1:$ средние пользовательские оценки игр для платформы Xbox One и персонального компьютера разные.
Проверим нулевую гипотезу о равенстве двух средних при уровне статистической значимости равном 0,05.
alpha = .05
results = st.ttest_ind(
actual_data.loc[(actual_data['platform'] == 'xone') &
(actual_data['user_score'] >= 0), 'user_score'],
actual_data.loc[(actual_data['platform'] == 'pc') &
(actual_data['user_score'] >= 0), 'user_score']
)
print('p-значение:', results.pvalue.round(3))
if results.pvalue < alpha:
print("Отвергаем нулевую гипотезу")
else:
print("Не получилось отвергнуть нулевую гипотезу")
p-значение: 0.564 Не получилось отвергнуть нулевую гипотезу
Результат проверки: нулевая гипотеза о равенстве средних пользовательских оценок игр для платформы Xbox One и персонального компьютера может быть принята.
Средние пользовательские оценки игр для платформы Xbox One и персонального компьютера равны.
print('Средняя пользовательская оценка игр для платформы Xbox One:',
actual_data.loc[(actual_data['platform'] == 'xone') &
(actual_data['user_score'] >= 0),
'user_score'].mean().round(1))
print('Средняя пользовательская оценка игр для персонального компьютера:',
actual_data.loc[(actual_data['platform'] == 'pc') &
(actual_data['user_score'] >= 0),
'user_score'].mean().round(1))
Средняя пользовательская оценка игр для платформы Xbox One: 6.5 Средняя пользовательская оценка игр для персонального компьютера: 6.4
Сформулируем нулевую и альтернативную гипотезы.
$H_0:$ средние пользовательские оценки жанров экшен и спортивные игры равны.
$H_1:$ средние пользовательские оценки жанров экшен и спортивные игры разные.
Проверим нулевую гипотезу о равенстве двух средних при уровне статистической значимости равном 0,05.
alpha = .05
results = st.ttest_ind(
actual_data.loc[(actual_data['genre'] == 'action') &
(actual_data['user_score'] >= 0), 'user_score'],
actual_data.loc[(actual_data['genre'] == 'sports') &
(actual_data['user_score'] >= 0), 'user_score']
)
print('p-значение:', f'{results.pvalue:.1}')
if results.pvalue < alpha:
print("Отвергаем нулевую гипотезу")
else:
print("Не получилось отвергнуть нулевую гипотезу")
p-значение: 4e-26 Отвергаем нулевую гипотезу
Результат проверки: нулевая гипотеза о равенстве средних пользовательских оценок для игр жанров экшен и спортивные игры не может быть принята. Может быть принята альтернативная гипотеза о наличии различий в средних пользовательских оценках для игр жанров экшен и спортивные игры.
Средние оценки пользователей для игр жанра экшен и спортивные игры различны, различия достоверны при p < 0,001.
print('Средняя пользовательская оценка игр жанра экшен:',
actual_data.loc[(actual_data['genre'] == 'action') &
(actual_data['user_score'] >= 0),
'user_score'].mean().round(1))
print('Средняя пользовательская оценка игр жанра спортивные игры:',
actual_data.loc[(actual_data['genre'] == 'sports') &
(actual_data['user_score'] >= 0),
'user_score'].mean().round(1))
Средняя пользовательская оценка игр жанра экшен: 6.8 Средняя пользовательская оценка игр жанра спортивные игры: 5.5
*Характеристики компьютерных игр*
Рассмотренные нами данные охватывают временной период в 40 лет: с 1977 по 2016 год. В течение этого срока было выпущено более 16,5 тысяч компьютерных игр. Новые игры выпускались каждый год.
Наименее продуктивными были 1977-1990 года, тогда выпускалось не более 50 игр в год. Рост количества выпускаемых в год игр стал заметен в середине 1990-х годов. К 2000-му году количество выпускаемых в год игр перевалило за 300 и к этому моменту не снижалось уже на протяжении трёх лет. С ещё большими темпами рост наблюдался в 2000-х годах и к концу первого десятилетия XXI века достиг своего максимума.
Большинство игр выпускалось с 1997 года, то есть в течение последних 20 лет. Самым продуктивным десятилетием было время с 2002 по 2011 года, тогда в свет выходило не менее 750 игр каждый год. Самыми продуктивными были 2008 и 2009 года, тогда было выпущено по 1400 новых игр. После 2011 года количество выпускаемых в год игр сократилось в два раза и к 2016 году сохраняется на уровне 600 новых игр в год.
Своеобразным экватором стал 2007 год: к этому моменту было произведено 50 % всех, остальные 50 % были выпущены на рынок с 2007 по 2016 года. Таким образом, за последние 10 лет мир увидел половину из когда-либо выпущенных компьютерных игр. А индустрия компьютерных игр воспроизвела свой объём.
За 40 лет сменилось 7 поколений игровых систем. Если для 2-го и 3-го поколений игровых систем выпускалось около 100–150 игр, то начиная с 4-го поколения игровых систем количество выпускавшихся игр начало расти. И каждый раз, при смене поколений количество выпускавшихся новых игр увеличивалось почти в два раза. Пик пришёлся на 7-е поколение. Для игровых систем этого поколения было выпущено 7800 игр, что составляет около 50 % всех игр. Количество игр для игровых систем последнего, 8-го поколения снизилось почти в два раза по сравнению с системами 7-го поколения. Однако итоговые оценки для игровых систем 8-го поколения делать рано.
Все игры выпущены для игровых платформ различных поколений. Среди них 30 игровых приставок 8 производителей, а также персональный компьютер. Среди производителей игровых платформ можно выделить тройку лидеров: Sony, Nintendo и Microsoft. Именно они на 2016 год продолжают свою деятельность в индустрии игровых консолей. Всего на тройку лидеров приходится более 91 % всех игр. Наибольшее количество игр было выпущено для игровых приставок производства Sony и Nintendo — 40 % и 37 % от общего числа игр, соответственно. Замыкает тройку лидеров Microsoft: для приставок её производства было выпущено игр почти в 3 раза меньше — 14 % всех игр.
Лидерами среди игровых платформ по количеству выпущенных за всё время для них игр являются Sony PlayStation 2 и Nintendo DS. Их доли на рынке одинаковые, а вместе на них приходится около 25 % всех игр. Кроме этих платформ в топ-10 по количеству выпущенных игр входят Sony PlayStation и PlayStation 3, Nintendo Wii и Microsoft Xbox 360. Для каждой из них было выпущено игр в 1,7 раз меньше по сравнению с лидерами. Для всех этих платформ выпущено более 1000 разных игр. Для остальных платформ выпущено меньшее количество игр. Своеобразной границей служит выступающий в качестве игровой платформы персональный компьютер. Для него было выпущено почти 1000 игр. Замыкают топ-10 платформы Microsoft Xbox и Nintendo Game Boy Advance. На все игровые платформы из топ-10 приходится почти 80 % всех выпущенных игр.
75 % игр были выпущены единожды. 25 % игр были выпущены несколько раз: в разные годы и/или для разных игровых платформ. Например, игра Need for speed: most wanted перевыпускалась 12 раз для разных платформ и в разных года, а Lego marvel super heroes, FIFA 14, Ratatouille, Madden NFL 07 выпускались по 9 раз каждая на разных платформах.
Игры разделены по 11 основным жанрам, которые охватывают 90 % всех игр. Наибольшее количество игр представлено в жанре экшен — 20 % всех игр. Примерно в 1,5 раза меньше представлено спортивных игр. Вместе на двух лидеров приходится 34 % всех выпущенных игр. В 2 раза меньше, чем у лидера представлен каждый из жанров: ролевые игры, шутер, квест и гонки. Ещё меньше игр жанров платформеры, симулятора и файтинги. Замыкают список жанров стратегии и квесты-головоломки.
*Распределение оценок и рейтинговая система*
Из всех игр только для 46 % пользователи поставили оценку. Оценки выставлялись по 10-балльной шкале с шагом 0,1 балла. Минимальная выставленная оценка — 0, максимальная — 9,7. Большинство оценённых игр имеют оценку не менее 4. Пользователи ставили достаточно высокие оценки: в среднем — 7 баллов из 10. А половина всех оценённых игр имеет оценку не ниже 7,5. Максимальное число оценок приходится на интервал от 7 до 9. Самая распространённая оценка — 7,8. Всё это позволяет утверждать, что пользователи достаточно лояльно относятся к тем играм, которые оценивали. И что, вероятно, мотивацией к выставлению оценки послужило именно хорошее впечатление об игре.
Количество оценённых критиками игр почти такое же, как оценённое пользователями. Только для 49 % всех игр критики поставили оценку. Минимальная выставленная оценка — 13, максимальная — 98. Оценки выставлялись по 100-балльной шкале с шагом 1 балл. Большинство оценённых игр имеют оценку не менее 37. Критики выставили достаточно высокие оценки: в среднем — 69 баллов из 100. А половина всех оценённых игр имеет оценку не ниже 71. Причём оценки 70 и 71 являются самыми распространёнными. Максимальное число оценок приходится на интервал 70–80. Всё это позволяет утверждать, что критики составили для себя положительное впечатление об играх и высоко их оценили.
Не все игры имеют рейтинг ESRB. Только 60 % всех игр ESRB присвоила рейтинг и возрастную категорию. Игры между категориями разделились неравномерно. Наибольшему числу игр присвоена категория Everyone ("Для всех») — 40 % от игр с присвоенной категорией. Следующая по ёмкости категория — Teen ("Для подростков от 13 лет"), 30 % от игр с присвоенной категорией. Затем идут приблизительно равные по ёмкости категории: Everyone 10+ ("Для детей от 10 лет") и Mature 17+ ("Для подростков от 17 лет»). Совместно на эти категории приходится оставшиеся 30 %.
*Характеристики продаж*
Всего за 40 лет в мире было продано более 8,9 млрд копий компьютерных игр. Минимальное количество проданных копий одной игры — 10 тыс., максимальное — 82,54 млн. В среднем по миру игры продавались в объёме 170 тыс. копий каждая. Большинство игр было продано в объёме не более 1,1 млн копий каждая. Игры, проданные в большем объёме, — явление редкое. Наиболее часто игры продаются в объёме 10–130 тыс. копий.
В Северной Америке продавалось только 73 % всех игр — более 12 тысяч наименований. Объём проданных копий достигает 4,4 млрд. Минимальное количество проданных копий одной игры — 10 тыс., максимальное — 41,36 млн. В среднем, в Северной Америке, игры продавались в объёме 140 тыс. копий каждая. Большинство игр было продано в объёме не более 750 тыс. копий каждая. Наиболее часто игры продаются в объёме 10–100 тыс. копий.
В Европе продавалось только 65 % всех игр — почти 11 тысяч наименований. Объём проданных копий достигает 2,4 млрд. Минимальное количество проданных копий одной игры — 10 тыс., максимальное — 28,96 млн. В среднем, в Европе, игры продавались в объёме 70 тыс. копий каждая. Большинство игр было продано в объёме не более 500 тыс. копий каждая. Наиболее часто игры продаются в объёме 10–120 тыс. копий.
В Японии продавалось только 37 % всех игр — более 6 тысяч наименований. Объём проданных копий достигает 1,3 млрд. Минимальное количество проданных копий одной игры — 10 тыс., максимальное — 10,22 млн. В среднем, в Японии, игры продавались в объёме 70 тыс. копий каждая. Большинство игр было продано в объёме не более 450 тыс. копий каждая. Наиболее часто игры продаются в объёме 10–100 тыс. копий.
В остальных регионах продавался только 61 % всех игр — более 10 тысяч наименований. Объём проданных копий достигает 800 млн. Минимальное количество проданных копий одной игры — 10 тыс., максимальное — 10,57 млн. В среднем игры в остальных регионах продавались в объёме 20 тыс. копий каждая. Большинство игр было продано в объёме не более 180 тыс. копий каждая. Наиболее часто игры продаются в объёме 10–100 тыс. копий.
Таким образом, наиболее ёмким является рынок компьютерных игр в регионе Северная Америка, на втором месте — Европейский союз и замыкает тройку — Япония.
*Выбор актуальных данных для построения прогноза*
Цикл жизни (то есть время оборота на рынке компьютерных игр) одного поколения игровых систем составляет примерно 10–15 лет. Появление игровых систем нового поколения приходится на середину жизненного цикла предыдущего поколения и практически всегда совпадает с уходом с рынка предпредыдущего поколения. Поэтому можно утверждать, что на рынке одновременно могут присутствовать игровые системы только двух, идущих подряд поколений. А игровые системы остальных поколений полностью вытесняются ими с рынка, поскольку игры для них перестают выпускаться разработчиками.
Смена игровых платформ у каждого производителя происходит схожим образом. Производитель выпускает на рынок новую платформу, когда продажи игр для предыдущей находятся в максимуме или уже начинают падать. Такую ситуацию можно объяснить по-разному. Выпуск новой платформы является либо следствием падения продаж игр для предыдущей платформы. Или же выпуск новой игровой платформы приводит к снижению интереса к предыдущей платформе.
В 2016 году на рынке можно найти игры для приставок 3 производителей (Sony, Nintendo и Microsoft), а также для персонального компьютера. Всего 9 игровых платформ. Среди 8 игровых приставок можно выделить Sony PlayStation 3 и PlayStation 4, портативную PlayStation Vita, Nintendo Wii и WiiU, портативную Nintendo 3DS, Microsoft Xbox 360 и Xbox One.
Жизненный цикл одной игровой приставки (особенно популярной) практически повторяет жизненный цикл поколений игровых систем: игры для одной игровой приставки выпускают на протяжении 10–12 лет. Платформы Sony PlayStation 3, Nintendo Wii и Microsoft Xbox 360 на рынке уже 11–12 лет. Максимум продаж для этих платформ уже остался в прошлом. И сейчас продажи игр для них находятся на самом низком уровне. По-видимому, поддерживаются выходом совсем небольшого числа новых игр. Наиболее вероятно, что в 2017 году они не будут актуальны.
Актуальными для прогноза продаж являются игровые платформы Sony: домашняя игровая приставка PlayStation 4 и портативная игровая приставка PlayStation Vita; платформы Nintendo: домашняя игровая приставка WiiU и портативная игровая приставка Nintendo 3DS; платформа Microsoft: домашняя игровая приставка Xbox One, а также персональный компьютер, игры для которого разрабатываются и выпускаются в стабильном режиме уже более 32 лет.
*Распределение игр по платформам*
Среди игр для домашних игровых консолей наименьший спрос получили игры для Nintendo WiiU (20 млн копий в год), в два раза больший — для Microsoft Xbox One (40 млн копий в год), и ещё в два раза больший — для Sony PlayStation 4 (80 млн копий в год). Среди игр для портативных игровых приставок меньшим спросом пользуются игры для PlayStation Vita (10 млн копий в год), а для Nintendo 3DS — в 4 раза более высоким (40 млн копий в год). Особняком стоит персональный компьютер: игры для него пользуются невысоким, но стабильным спросом — 15 млн копий в год.
Средний объём годовых продаж для PlayStation 3 и Nintendo Wii примерно на 10 млн копий меньше, чем у платформ, пришедших им на смену. Средний годовой объём продаж и размах значений у Microsoft Xbox 360 выше на 20 млн копий, чем у Xbox One. Однако объёмы продаж игр для этих платформ находятся в минимуме и уже не достигнут средних значений, поскольку продажи для них прошли максимум. Портативные игровые приставки Nintendo DS и Sony PlayStation Portable в среднем имели более низкий объём продаж, чем платформы, пришедшие им на смену.
Игры для домашних приставок в среднем пользуются большим спросом, чем игры для портативных приставок или для персонального компьютера. Одна игра для домашних приставок распространяется в среднем по 200 тыс. копий. 50 % всех игр для каждой платформы Sony PlayStation 4 или Microsoft Xbox One может продаваться в объёме 50–700 тыс. копий одной игры и в объёме 100–500 тыс. копий одной игры среди игр для Nintendo WiiU.
Средние объёмы продаж копий одной игры для Sony PlayStation 3 и Microsoft Xbox 360 находятся на таком же уровне как у платформ, пришедших им на смену. Несколько меньше, чем для Nintendo WiiU, продаётся копий одной игры для Nintendo Wii.
Для портативных игровых приставок объём продаж одной игры меньше: для PlayStation Vita — 50 тыс. копий, для Nintendo 3DS — 100 тыс. копий. Объём продаж игр для портативных приставок может достигать объёма 300 тыс. копий — для игр на Sony PlayStation Vita, 700 тыс. копий — для игр на Nintendo 3DS.
Ушедшая с рынка Sony PlayStation Portable имела объём продаж одной игры на уровне с Sony PlayStation Vita. Объём продаж одной игры для Nintendo DS был ниже, чем для Nintendo 3DS.
Игры для персонального компьютера продаются в среднем на таком же уровне, как и для портативных игровых платформ. — 100 тыс. копий. Но могут достигать отметки в 550 тыс. копий.
*Влияние оценок пользователей и критиков*
Объём мировых продаж не коррелирует с оценкой пользователей. Видимо, пользователи очень субъективно выставляют оценку. Особенно в случае, если выход игры был ожидаем (и поэтому продажи оказались высокими), а вот ожиданий пользователей игра не оправдала.
А вот с оценкой критиков у объёмов продаж есть умеренная корреляция. Зависимость не носит линейный характер, поэтому коэффициент корреляции не будет высоким. Он находится на уровне 0,29–0,42. Однако высокой оценке игры со стороны критиков соответствует высокий объём продаж и, наоборот, игры с низкой экспертной оценкой подкреплены низкими продажами. Интересен тот факт, что с увеличением оценки критиков до среднего значения в 70 баллов наблюдается медленный рост продаж. Но при дальнейшем увеличении до 90 баллов наблюдается более интенсивный рост продаж, в среднем достигающий объёмов в 1 млн проданных копий.
И хотя объёмы продаж не коррелируют с оценками пользователей, важно всё-таки понимать насколько продаваемые игры буду удовлетворять пользователей. В целом, можно утверждать, что и пользователи, и критики формируют об игре схожее мнение. В среднем высокой оценке критиков соответствует высокая оценка пользователей, низкой оценке критиков — низкая оценка пользователей. Главное, что высоко оценённые критиками и, соответственно, имеющие высокие объёмы продаж игры, вероятно, в конечном итоге, будут оценены также высоко и пользователями.
*Распределение игр по жанрам*
Наибольший объём продаж имеют игры жанров экшен, шутеры и ролевые игры. Спортивные игры и на одинаковом уровне платформеры и гонки замыкают топ-5 игр с самым высоким объёмом продаж. Хуже всего продаются головоломки, стратегии и квесты. Наибольшее число копий одной игры продаётся в жанре шутер. В среднем одна игра продаётся в объёме 450 тыс. копий. Следующими по величине объёма продаж одной игры идут платформеры и спортивные игры. В среднем одна игра продаётся в объёме 250 тыс. копий (платформеры) и 200 тыс. копий (спортивные игры). У лидеров по общим суммарным продажам — экшенов и ролевых игр — медианные значения объёмов продаж одной игры низкие: 100–200 тыс. копий.
*Портрет пользователя каждого региона*
Пользователи в Северной Америке, Европе и других регионах схожи в своих предпочтениях. Предпочтения пользователей из Японии кардинально от них отличаются.
Наибольшим спросом в Северной Америке пользуются платформы Microsoft Xbox 360, Sony PlayStation 4 и PlayStation 3, занимающие 24 %, 18 % и 18 % рынка, соответственно. Замыкают топ-5 платформы Microsoft Xbox One и Nintendo 3DS, занимающие 16 % и 9 %, соответственно. Пользователи предпочитают играть в экшены и шутеры (30 % и 25 % рынка, соответственно), во вторую очередь в спортивные и ролевые игры (14 % и 11 % рынка, соответственно). Игры будут иметь более высокий объём продаж, если им присвоена категория рейтинга ESRB. Если сравнивать объёмы продаж игр в зависимости от наличия категории рейтинга ESRB, то можно утверждать, что объём продаж игр с присвоенным рейтингом в 5 раз выше объёма продаж игр без рейтинга. Хотя количество наименований таких игр соотносится как 1 : 1.
Наибольшим спросом в Евросоюзе пользуются платформы Sony PlayStation 4 и PlayStation 3, а также Microsoft Xbox 360, занимающие 28 %, 21 % и 15 % рынка, соответственно. Замыкают топ-5 платформы Microsoft Xbox One и Nintendo 3DS, занимающие каждая 10 % и 8 % рынка, соответственно. Пользователи предпочитают играть в экшены и шутеры (32 % и 22 % рынка, соответственно), во вторую очередь в спортивные и ролевые игры (14 % и 10 % рынка, соответственно). И здесь игры будут иметь более высокий объём продаж, если им присвоена категория рейтинга ESRB: объём продаж игр с присвоенным рейтингом в 4,5 раза выше объёма продаж игр без рейтинга.
В других регионах (кроме Японии) наибольшим спросом пользуются платформы Sony PlayStation 4 и PlayStation 3, Microsoft Xbox 360, занимающие 31 %, 28 % и 13 % рынка, соответственно. Замыкают топ-5 платформы Microsoft Xbox One и Nintendo 3DS, занимающие 9 % и 6 % рынка, соответственно. Пользователи предпочитают играть в экшены и шутеры (33 % и 24 % рынка, соответственно), во вторую очередь в спортивные и ролевые игры (14 % и 10 % рынка, соответственно). Игра имеет более высокий объём продаж, если ей присвоена категория рейтинга ESRB. И в этих регионах объём продаж игр с присвоенным рейтингом в 4 раза выше объёма продаж игр без рейтинга.
Наибольшим спросом в Японии пользуются платформы Nintendo 3DS, Sony PlayStation 3 и Sony PlayStation Vita, занимающие 46 %, 18 % и 11 % рынка, соответственно. Замыкают топ-5 платформы Sony PlayStation 4 и Nintendo WiiU, занимающие 8 % и 7 % рынка, соответственно. Не пользуются спросом совсем платформа Microsoft Xbox One и персональный компьютер. Пользователи преимущественно предпочитают играть в ролевые игры и экшены (34 % и 27 % рынка, соответственно), остальные жанры не пользуются большим спросом (менее 7 % от объёма рынка). Игра имеет более высокий объём продаж, если ей не присвоена категория рейтинга ESRB. Видимо, поскольку организация ESRB ведёт свою деятельность в США, то прежде всего работает с играми, распространяемыми на территории США. В Японии же выпускается много игр, распространяемых только на территории Японии, поэтому они зачастую не имеют рейтинга ESRB.
Таким образом, можно рекомендовать в предложении интернет-магазина собрать игры:
Стоит меньше уделять внимание играм приставок Sony PlayStation 3 и PlayStation Portable, Nintendo Wii и DS, Microsoft Xbox 360, поскольку продажи игр для них находятся в минимуме и уже не вырастут.
Рекламную кампанию проводить: